|
| 1 | +/- |
| 2 | +Copyright (c) 2026 Yury G. Kudryashov. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Yury G. Kudryashov |
| 5 | +-/ |
| 6 | +module |
| 7 | + |
| 8 | +public import Mathlib.Analysis.Complex.UpperHalfPlane.MoebiusAction |
| 9 | +public import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.FinTwo |
| 10 | +import Mathlib.LinearAlgebra.Matrix.GeneralLinearGroup.Basic |
| 11 | +import Mathlib.Algebra.QuadraticDiscriminant |
| 12 | + |
| 13 | +/-! |
| 14 | +# Fixed points of isometries of the upper half-plane |
| 15 | +
|
| 16 | +In this file we show that the scalar multiplication by an element `g : GL (Fin 2) ℝ` |
| 17 | +has the following set of fixed points, depending on `g`. |
| 18 | +
|
| 19 | +- if `g` preserves orientation (i.e., has positive determinant) and is an elliptic matrix, |
| 20 | + then `z ↦ g • z` has a unique fixed point; |
| 21 | +- if `g` is a scalar matrix, then it acts by the identity map (proved upstream of this file); |
| 22 | +- if `g` preserves orientation, and is a parabolic or a hyperbolic matrix, |
| 23 | + then it has no fixed points; |
| 24 | +- if `g` reverses orientation and has zero trace, then it has a geodesic line of fixed points; |
| 25 | + - if `g 1 0 = 0`, then this is the vertical line `re z = g 0 1 / (2 * g 1 1)`; |
| 26 | + - otherwise, it's a half-circle with its center on the real axis; |
| 27 | +- if `g` reverses orientation and has nonzero trace, then it has no fixed points. |
| 28 | +
|
| 29 | +As a corollary of this classification, we conclude that `PSL(2, ℝ)` acts faithfully |
| 30 | +on the upper half-plane. |
| 31 | +-/ |
| 32 | + |
| 33 | +open Matrix |
| 34 | +open scoped MatrixGroups ComplexConjugate |
| 35 | + |
| 36 | +public noncomputable section |
| 37 | + |
| 38 | +namespace UpperHalfPlane |
| 39 | + |
| 40 | +section GLAction |
| 41 | + |
| 42 | +variable {g : GL (Fin 2) ℝ} {z w : ℍ} |
| 43 | + |
| 44 | +theorem gl_smul_eq_iff_num_eq : |
| 45 | + g • z = w ↔ num g z = σ g w * denom g z := by |
| 46 | + rw [← (σ g).injective.eq_iff] |
| 47 | + simp [UpperHalfPlane.ext_iff, coe_smul, div_eq_iff] |
| 48 | + |
| 49 | +/-- If `g` is an upper triangular matrix with trace zero, |
| 50 | +then `g` fixes the vertical line `re z = b / (2 * d)`. -/ |
| 51 | +theorem gl_smul_eq_self_iff_re_eq (htrace : g.val.trace = 0) (hc : g 1 0 = 0) : |
| 52 | + g • z = z ↔ z.re = g 0 1 / (2 * g 1 1) := by |
| 53 | + rw [Matrix.trace_fin_two, add_eq_zero_iff_eq_neg] at htrace |
| 54 | + have h₀ : g 1 1 ≠ 0 := by |
| 55 | + intro h₀ |
| 56 | + simpa [Matrix.det_fin_two, hc, h₀] using g.det_ne_zero |
| 57 | + have h : g.val.det < 0 := by simp [Matrix.det_fin_two, *] |
| 58 | + simp [gl_smul_eq_iff_num_eq, Complex.ext_iff, htrace, hc, num, denom, σ, h.not_gt, mul_comm, |
| 59 | + eq_div_iff, h₀] |
| 60 | + grind |
| 61 | + |
| 62 | +/-- If `g` is an orientation reversing matrix with trace zero and `c ≠ 0`, |
| 63 | +then its action on the upper half plane has a half-circle of fixed points. |
| 64 | +In the hyperbolic geometry, this half-circle is a line. |
| 65 | +If `c = 0`, then this line is a vertical half-line in the usual geometry, |
| 66 | +see `gl_smul_eq_self_iff_re_eq`. -/ |
| 67 | +theorem gl_smul_eq_self_iff_dist_sq_eq (h : g.val.det < 0) (htrace : g.val.trace = 0) |
| 68 | + (hc : g 1 0 ≠ 0) : |
| 69 | + g • z = z ↔ dist (z : ℂ) (-g 1 1 / g 1 0) ^ 2 = (-g.val.det) / g 1 0 ^ 2 := by |
| 70 | + rw [Matrix.trace_fin_two, ← eq_neg_iff_add_eq_zero] at htrace |
| 71 | + rw [eq_div_iff (by positivity), dist_eq_norm, ← Complex.normSq_eq_norm_sq, Complex.normSq_apply, |
| 72 | + gl_smul_eq_iff_num_eq, σ, g.val_det_apply, if_neg h.not_gt] |
| 73 | + simp [num, denom, Complex.ext_iff, htrace, Matrix.det_fin_two, field] |
| 74 | + grind |
| 75 | + |
| 76 | +/-- If `g` is an orientation reversing matrix with trace zero and `c ≠ 0`, |
| 77 | +then its action on the upper half plane has a half-circle of fixed points. |
| 78 | +In the hyperbolic geometry, this half-circle is a line. -/ |
| 79 | +theorem gl_smul_eq_self_iff_dist_eq (h : g.val.det < 0) (htrace : g.val.trace = 0) |
| 80 | + (hc : g 1 0 ≠ 0) : |
| 81 | + g • z = z ↔ dist (z : ℂ) (-g 1 1 / g 1 0) = √(-g.val.det) / |g 1 0| := by |
| 82 | + rw [gl_smul_eq_self_iff_dist_sq_eq h htrace hc, eq_comm, ← Real.sqrt_eq_iff_eq_sq, eq_comm, |
| 83 | + Real.sqrt_div', Real.sqrt_sq_eq_abs] <;> positivity [neg_pos.mpr h] |
| 84 | + |
| 85 | +/-- An orientation-reversing isometry of the hyperbolic plane has a fixed point |
| 86 | +iff the corresponding matrix has zero trace. -/ |
| 87 | +theorem exists_gl_smul_eq_self_iff_trace_eq_zero (h : g.val.det < 0) : |
| 88 | + (∃ z : ℍ, g • z = z) ↔ g.val.trace = 0 := by |
| 89 | + constructor |
| 90 | + · rintro ⟨z, hz⟩ |
| 91 | + linear_combination |
| 92 | + (norm := { simp [σ, h.not_gt, num, denom, z.im_ne_zero, Matrix.trace_fin_two, field] }) |
| 93 | + congr($(gl_smul_eq_iff_num_eq.mp hz).im / z.im) |
| 94 | + · intro hadd |
| 95 | + by_cases hc : g 1 0 = 0 |
| 96 | + · use ⟨⟨g 0 1 / (2 * g 1 1), 1⟩, one_pos⟩ |
| 97 | + simp [gl_smul_eq_self_iff_re_eq, *] |
| 98 | + · use ⟨⟨-g 1 1 / g 1 0, √(-g.val.det) / |g 1 0|⟩, by simp [*]⟩ |
| 99 | + simp [gl_smul_eq_self_iff_dist_sq_eq, *, dist_eq_norm, ← Complex.normSq_eq_norm_sq, |
| 100 | + Complex.normSq_apply, ← pow_two, div_pow, h.le] |
| 101 | + |
| 102 | +/-- If `g` is an orientation-preserving map, |
| 103 | +then the fixed points of its action on the upper half-plane |
| 104 | +can be found from a quadratic equation. |
| 105 | +
|
| 106 | +If `c ≠ 0`, then this equation has a unique solution in the upper half-plane |
| 107 | +given by `UpperHalfPlane.fixedPt`. |
| 108 | +If `c = 0`, then the equation degenerates to a linear equation, |
| 109 | +which has no solutions in the upper half-plane unless `g` is a scalar matrix. |
| 110 | +
|
| 111 | +See also `Matrix.GeneralLinearGroup.fixpointPolynomial_aeval_eq_zero_iff` |
| 112 | +for a similar lemma about the action on the projective line, |
| 113 | +encoded as `OnePoint R`, where `R` is the ring of coefficients. |
| 114 | +-/ |
| 115 | +theorem gl_smul_eq_self_iff_quadratic (h : 0 < g.val.det) : |
| 116 | + g • z = z ↔ (g 1 0 * (z * z) + (g 1 1 - g 0 0) * z + -g 0 1 : ℂ) = 0 := by |
| 117 | + simp [gl_smul_eq_iff_num_eq, σ, h, num, denom] |
| 118 | + grind |
| 119 | + |
| 120 | +/-- If `g` is a non-scalar orientation perserving matrix with a fixed point in `ℍ`, |
| 121 | +then it's an elliptic matrix. -/ |
| 122 | +theorem isElliptic_of_exists_smul_eq_self (h : 0 < g.val.det) (hgc : g ∉ Subgroup.center _) |
| 123 | + (hfix : ∃ z : ℍ, g • z = z) : g.IsElliptic := by |
| 124 | + rcases hfix with ⟨z, hz⟩ |
| 125 | + have hc : g 1 0 ≠ 0 := by |
| 126 | + intro hc |
| 127 | + simp [GeneralLinearGroup.mem_center_iff_val_mem_range_scalar, ← Matrix.ext_iff, hc] at hgc |
| 128 | + simp [gl_smul_eq_iff_num_eq, Complex.ext_iff, σ, h, num, denom, hc, mul_comm, z.im_ne_zero] |
| 129 | + at hz |
| 130 | + grind |
| 131 | + refine lt_of_not_ge fun hge ↦ ?_ |
| 132 | + have hd : discrim (g 1 0 : ℂ) (g 1 1 - g 0 0) (-g 0 1) = √g.val.discr * √g.val.discr := by |
| 133 | + rw [← Complex.ofReal_mul, Real.mul_self_sqrt hge] |
| 134 | + simp [discrim, Matrix.discr_fin_two, Matrix.trace_fin_two, Matrix.det_fin_two] |
| 135 | + ring |
| 136 | + rw [gl_smul_eq_self_iff_quadratic h, quadratic_eq_zero_iff (mod_cast hc) hd] at hz |
| 137 | + norm_cast at hz |
| 138 | + simp only [z.ne_ofReal, false_or] at hz |
| 139 | + |
| 140 | +/-- The unique fixed point of an orientation-preserving elliptic matrix acting on `ℍ`. -/ |
| 141 | +def fixedPt (g : GL (Fin 2) ℝ) (hell : g.IsElliptic) : ℍ := |
| 142 | + ⟨(g 0 0 - g 1 1) / (2 * g 1 0) + .I * (√(-g.val.discr) / (2 * |g 1 0|)), by |
| 143 | + simpa [div_pos, Complex.div_re, Complex.div_im, hell.c_ne_zero]⟩ |
| 144 | + |
| 145 | +@[simp] |
| 146 | +theorem fixedPt_neg (hg : (-g).IsElliptic) : |
| 147 | + fixedPt (-g) hg = fixedPt g (isElliptic_neg_iff.mp hg) := by |
| 148 | + ext |
| 149 | + simp [fixedPt, Matrix.discr_fin_two, Matrix.det_neg] |
| 150 | + ring |
| 151 | + |
| 152 | +/-- The action of an elliptic orientation preserving matrix on `ℍ` |
| 153 | +has a unique fixed point given by `fixedPt`. -/ |
| 154 | +theorem gl_smul_eq_self_iff_eq_fixedPt (hpos : 0 < g.val.det) (hell : g.IsElliptic) : |
| 155 | + g • z = z ↔ z = fixedPt g hell := by |
| 156 | + wlog hc : 0 < g 1 0 generalizing g |
| 157 | + · replace hc := hell.c_ne_zero.lt_or_gt.resolve_right hc |
| 158 | + simpa using @this (-g) (by simpa [Matrix.det_neg]) hell.neg (by simpa) |
| 159 | + have hd : discrim (g 1 0 : ℂ) (g 1 1 - g 0 0) (-g 0 1) = (.I * √(-g.val.discr)) ^ 2 := by |
| 160 | + rw [mul_pow, ← Complex.ofReal_pow, Real.sq_sqrt] |
| 161 | + · simp [discrim, Matrix.discr_fin_two, Matrix.trace_fin_two, Matrix.det_fin_two] |
| 162 | + grind |
| 163 | + · simpa using hell.le |
| 164 | + rw [gl_smul_eq_self_iff_quadratic hpos, quadratic_eq_zero_iff (mod_cast hell.c_ne_zero) |
| 165 | + (hd.trans (pow_two _))] |
| 166 | + rw [or_iff_left] |
| 167 | + · simp [fixedPt, UpperHalfPlane.ext_iff, abs_of_pos hc, field] |
| 168 | + · intro h |
| 169 | + refine z.im_pos.not_ge ?_ |
| 170 | + rw [← coe_im, h] |
| 171 | + simp [Complex.div_im, div_nonpos_iff, hc.le, mul_nonneg] |
| 172 | + |
| 173 | +theorem gl_smul_I_eq_I_iff_of_pos {g : GL (Fin 2) ℝ} (hg : 0 < g.det.val) : |
| 174 | + g • I = I ↔ g 0 0 = g 1 1 ∧ g 0 1 = -g 1 0 := by |
| 175 | + rw [gl_smul_eq_iff_num_eq, σ, if_pos hg] |
| 176 | + simp [Complex.ext_iff, num, denom, and_comm] |
| 177 | + |
| 178 | +theorem gl_smul_I_eq_I_iff_of_neg {g : GL (Fin 2) ℝ} (hg : g.det.val < 0) : |
| 179 | + g • I = I ↔ g 0 0 = -g 1 1 ∧ g 0 1 = g 1 0 := by |
| 180 | + rw [gl_smul_eq_iff_num_eq, σ, if_neg (not_lt_of_gt hg)] |
| 181 | + simp [num, denom, Complex.ext_iff, and_comm] |
| 182 | + |
| 183 | +/-- A matrix acts trivially on `ℍ` iff it belongs to the center of `GL(2, ℝ)`, |
| 184 | +i.e., it's a diagonal matrix. -/ |
| 185 | +theorem forall_smul_eq_self_iff_mem_center {g : GL (Fin 2) ℝ} : |
| 186 | + (∀ z : ℍ, g • z = z) ↔ g ∈ Subgroup.center _ := by |
| 187 | + constructor |
| 188 | + · intro hg |
| 189 | + by_contra! hgc |
| 190 | + rcases g.det_ne_zero.lt_or_gt with hlt | hgt |
| 191 | + · obtain ⟨ha, hb⟩ := (gl_smul_I_eq_I_iff_of_neg hlt).mp (hg _) |
| 192 | + rw [eq_neg_iff_add_eq_zero, ← Matrix.trace_fin_two] at ha |
| 193 | + rcases eq_or_ne (g 1 0) 0 with hc | hc |
| 194 | + · specialize hg ⟨1 + .I, by simp⟩ |
| 195 | + rw [gl_smul_eq_self_iff_re_eq ha hc] at hg |
| 196 | + simp_all |
| 197 | + · have : 0 < 1 + √(-g.val.det) / |g 1 0| := by simp [add_pos, *] |
| 198 | + specialize hg ⟨⟨-g 1 1 / g 1 0, 1 + √(-g.val.det) / |g 1 0|⟩, this⟩ |
| 199 | + simp [gl_smul_eq_self_iff_dist_eq hlt ha hc, Complex.dist_eq_re_im, Real.sqrt_sq this.le] |
| 200 | + at hg |
| 201 | + · have := isElliptic_of_exists_smul_eq_self hgt hgc ⟨.I, hg _⟩ |
| 202 | + contrapose! hg |
| 203 | + simp [gl_smul_eq_self_iff_eq_fixedPt hgt this, exists_ne] |
| 204 | + · aesop (add simp GeneralLinearGroup.center_eq_range_scalar) |
| 205 | + |
| 206 | +end GLAction |
| 207 | + |
| 208 | +instance : FaithfulSMul PGL(2, ℝ) ℍ := by |
| 209 | + rw [faithfulSMul_iff] |
| 210 | + intro g |
| 211 | + cases g |
| 212 | + simp [forall_smul_eq_self_iff_mem_center] |
| 213 | + |
| 214 | +end UpperHalfPlane |
0 commit comments