@@ -5,6 +5,7 @@ Authors: Chris Birkbeck
5
5
-/
6
6
7
7
import Mathlib.LinearAlgebra.Matrix.SpecialLinearGroup
8
+ import Mathlib.Data.Int.Interval
8
9
9
10
/-!
10
11
# Matrices with fixed determinant
@@ -18,12 +19,13 @@ kbb (https://github.com/kim-em/kbb/tree/master) repository, so credit to those a
18
19
19
20
variable (n : Type *) [DecidableEq n] [Fintype n] (R : Type *) [CommRing R]
20
21
21
- /--The set of matrices with fixed determinant `m`. -/
22
+ /--The subtype of matrices with fixed determinant `m`. -/
22
23
def FixedDetMatrix (m : R) := { A : Matrix n n R // A.det = m }
23
24
24
- namespace FixedDetMatrix
25
+ namespace FixedDetMatrices
25
26
26
- open ModularGroup Matrix SpecialLinearGroup MatrixGroups
27
+ open Matrix hiding mul_smul
28
+ open ModularGroup SpecialLinearGroup MatrixGroups
27
29
28
30
/--Extensionality theorem for `FixedDetMatrix` with respect to the underlying matrix, not
29
31
entriwise. -/
@@ -52,4 +54,194 @@ lemma smul_coe (m : R) (g : SpecialLinearGroup n R) (A : FixedDetMatrix n R m) :
52
54
(g • A).1 = g * A.1 := by
53
55
rw [smul_def]
54
56
55
- end FixedDetMatrix
57
+ section IntegralFixedDetMatrices
58
+
59
+ local notation :1024 "Δ" m : 1024 => (FixedDetMatrix (Fin 2 ) ℤ m)
60
+
61
+ variable {m : ℤ}
62
+
63
+ /--Set of representatives for the orbits under `S` and `T`. -/
64
+ def reps (m : ℤ) : Set (Δ m) :=
65
+ {A : Δ m | (A.1 1 0 ) = 0 ∧ 0 < A.1 0 0 ∧ 0 ≤ A.1 0 1 ∧ |(A.1 0 1 )| < |(A.1 1 1 )|}
66
+
67
+ /--Reduction step for matrices in `Δ m` which moves the matrices towards `reps`.-/
68
+ def reduceStep (A : Δ m) : Δ m := S • (T ^ (-(A.1 0 0 / A.1 1 0 ))) • A
69
+
70
+ private lemma reduce_aux {A : Δ m} (h : (A.1 1 0 ) ≠ 0 ) :
71
+ |((reduceStep A).1 1 0 )| < |(A.1 1 0 )| := by
72
+ suffices ((reduceStep A).1 1 0 ) = A.1 0 0 % A.1 1 0 by
73
+ rw [this, abs_eq_self.mpr (Int.emod_nonneg (A.1 0 0 ) h)]
74
+ exact Int.emod_lt (A.1 0 0 ) h
75
+ simp_rw [Int.emod_def, sub_eq_add_neg, reduceStep, smul_coe, coe_T_zpow, S]
76
+ norm_num [vecMul, vecHead, vecTail, mul_comm]
77
+
78
+ /--Reduction lemma for integral FixedDetMatrices. -/
79
+ @[elab_as_elim]
80
+ def reduce_rec {C : Δ m → Sort *}
81
+ (base : ∀ A : Δ m, (A.1 1 0 ) = 0 → C A)
82
+ (step : ∀ A : Δ m, (A.1 1 0 ) ≠ 0 → C (reduceStep A) → C A) :
83
+ ∀ A, C A := fun A => by
84
+ by_cases h : (A.1 1 0 ) = 0
85
+ · exact base _ h
86
+ · exact step A h (reduce_rec base step (reduceStep A))
87
+ termination_by A => Int.natAbs (A.1 1 0 )
88
+ decreasing_by
89
+ zify
90
+ exact reduce_aux h
91
+
92
+ /--Map from `Δ m → Δ m` which reduces a FixedDetMatrix towards a representative element in reps. -/
93
+ def reduce : Δ m → Δ m := fun A ↦
94
+ if (A.1 1 0 ) = 0 then
95
+ if 0 < A.1 0 0 then (T ^ (-(A.1 0 1 / A.1 1 1 ))) • A else
96
+ (T ^ (-(-A.1 0 1 / -A.1 1 1 ))) • (S • (S • A)) --the -/- don't cancel with ℤ divs.
97
+ else
98
+ reduce (reduceStep A)
99
+ termination_by b => Int.natAbs (b.1 1 0 )
100
+ decreasing_by
101
+ next a h =>
102
+ zify
103
+ exact reduce_aux h
104
+
105
+ lemma reduce_of_pos {A : Δ m} (hc : (A.1 1 0 ) = 0 ) (ha : 0 < A.1 0 0 ) :
106
+ reduce A = (T ^ (-(A.1 0 1 / A.1 1 1 ))) • A := by
107
+ rw [reduce]
108
+ simp only [zpow_neg, Int.ediv_neg, neg_neg] at *
109
+ simp_rw [if_pos hc, if_pos ha]
110
+
111
+ lemma reduce_of_not_pos {A : Δ m} (hc : (A.1 1 0 ) = 0 ) (ha : ¬ 0 < A.1 0 0 ) :
112
+ reduce A = (T ^ (-(-A.1 0 1 / -A.1 1 1 ))) • (S • (S • A)) := by
113
+ rw [reduce]
114
+ simp only [abs_eq_zero, zpow_neg, Int.ediv_neg, neg_neg] at *
115
+ simp_rw [if_pos hc, if_neg ha]
116
+
117
+ @[simp]
118
+ lemma reduce_reduceStep {A : Δ m} (hc : (A.1 1 0 ) ≠ 0 ) :
119
+ reduce (reduceStep A) = reduce A := by
120
+ symm
121
+ rw [reduce, if_neg hc]
122
+
123
+ private lemma A_c_eq_zero {A : Δ m} (ha : A.1 1 0 = 0 ) : A.1 0 0 * A.1 1 1 = m := by
124
+ simpa only [det_fin_two, ha, mul_zero, sub_zero] using A.2
125
+
126
+ private lemma A_d_ne_zero {A : Δ m} (ha : A.1 1 0 = 0 ) (hm : m ≠ 0 ) : A.1 1 1 ≠ 0 :=
127
+ right_ne_zero_of_mul (A_c_eq_zero (ha) ▸ hm)
128
+
129
+ private lemma A_a_ne_zero {A : Δ m} (ha : A.1 1 0 = 0 ) (hm : m ≠ 0 ) : A.1 0 0 ≠ 0 :=
130
+ left_ne_zero_of_mul (A_c_eq_zero ha ▸ hm)
131
+
132
+ /--An auxiliary result bounding the size of the entries of the representatives in `reps`. -/
133
+ lemma reps_entries_le_m' {A : Δ m} (h : A ∈ reps m) (i j : Fin 2 ) :
134
+ A.1 i j ∈ Finset.Icc (-|m|) |m| := by
135
+ suffices |A.1 i j| ≤ |m| from Finset.mem_Icc.mpr <| abs_le.mp this
136
+ obtain ⟨h10, h00, h01, h11⟩ := h
137
+ have h1 : 0 < |A.1 1 1 | := (abs_nonneg _).trans_lt h11
138
+ have h2 : 0 < |A.1 0 0 | := abs_pos.mpr h00.ne'
139
+ fin_cases i <;> fin_cases j
140
+ · simpa only [← abs_mul, A_c_eq_zero h10] using (le_mul_iff_one_le_right h2).mpr h1
141
+ · simpa only [← abs_mul, A_c_eq_zero h10] using h11.le.trans (le_mul_of_one_le_left h1.le h2)
142
+ · simp_all
143
+ · simpa only [← abs_mul, A_c_eq_zero h10] using (le_mul_iff_one_le_left h1).mpr h2
144
+
145
+ @[simp]
146
+ lemma reps_zero_empty : reps 0 = ∅ := by
147
+ rw [reps, Set.eq_empty_iff_forall_not_mem]
148
+ rintro A ⟨h₁, h₂, -, h₄⟩
149
+ suffices |A.1 0 1 | < 0 by linarith [abs_nonneg (A.1 0 1 )]
150
+ have := A_c_eq_zero h₁
151
+ simp_all [h₂.ne']
152
+
153
+ noncomputable instance repsFintype (k : ℤ) : Fintype (reps k) := by
154
+ let H := Finset.Icc (-|k|) |k|
155
+ let H4 := Fin 2 → Fin 2 → H
156
+ apply Fintype.ofInjective (β := H4) (f := fun M i j ↦ ⟨M.1 .1 i j, reps_entries_le_m' M.2 i j⟩)
157
+ intro M N h
158
+ ext i j
159
+ simpa only [Subtype.mk.injEq] using congrFun₂ h i j
160
+
161
+ @[simp]
162
+ lemma S_smul_four (A : Δ m) : S • S • S • S • A = A := by
163
+ simp only [smul_def, ← mul_assoc, S_mul_S_eq, neg_mul, one_mul, mul_neg, neg_neg, Subtype.coe_eta]
164
+
165
+ @[simp]
166
+ lemma T_S_rel_smul (A : Δ m) : S • S • S • T • S • T • S • A = T⁻¹ • A := by
167
+ simp_rw [← T_S_rel, ← smul_assoc]
168
+
169
+ lemma reduce_mem_reps {m : ℤ} (hm : m ≠ 0 ) (A : Δ m) : reduce A ∈ reps m := by
170
+ induction A using reduce_rec with
171
+ | step A h1 h2 => simpa only [reduce_reduceStep h1] using h2
172
+ | base A h =>
173
+ have hd := A_d_ne_zero h hm
174
+ by_cases h1 : 0 < A.1 0 0
175
+ · simp only [reduce_of_pos h h1]
176
+ have h2 := Int.emod_def (A.1 0 1 ) (A.1 1 1 )
177
+ have h4 := Int.ediv_mul_le (A.1 0 1 ) hd
178
+ set n : ℤ := A.1 0 1 / A.1 1 1
179
+ have h3 := Int.emod_lt (A.1 0 1 ) hd
180
+ rw [← abs_eq_self.mpr <| Int.emod_nonneg _ hd] at h3
181
+ simp only [smul_def, Fin.isValue, coe_T_zpow]
182
+ suffices A.1 1 0 = 0 ∧ n * A.1 1 0 < A.1 0 0 ∧
183
+ n * A.1 1 1 ≤ A.1 0 1 ∧ |A.1 0 1 + -(n * A.1 1 1 )| < |A.1 1 1 | by
184
+ simpa only [reps, Fin.isValue, cons_mul, Nat.succ_eq_add_one, Nat.reduceAdd, empty_mul,
185
+ Equiv.symm_apply_apply, Set.mem_setOf_eq, of_apply, cons_val', vecMul, cons_dotProduct,
186
+ vecHead, one_mul, vecTail, Function.comp_apply, Fin.succ_zero_eq_one, neg_mul,
187
+ dotProduct_empty, add_zero, zero_mul, zero_add, empty_val', cons_val_fin_one,
188
+ cons_val_one, cons_val_zero, lt_add_neg_iff_add_lt, le_add_neg_iff_add_le]
189
+ simp_all only [h, mul_comm n, zero_mul, ← sub_eq_add_neg, ← h2,
190
+ Fin.isValue, h1, h3, and_true, true_and]
191
+ · simp only [reps, Fin.isValue, reduce_of_not_pos h h1, Int.ediv_neg, neg_neg, smul_def, ←
192
+ mul_assoc, S_mul_S_eq, neg_mul, one_mul, coe_T_zpow, mul_neg, cons_mul, Nat.succ_eq_add_one,
193
+ Nat.reduceAdd, empty_mul, Equiv.symm_apply_apply, neg_of, neg_cons, neg_empty,
194
+ Set.mem_setOf_eq, of_apply, cons_val', Pi.neg_apply, vecMul, cons_dotProduct, vecHead,
195
+ vecTail, Function.comp_apply, Fin.succ_zero_eq_one, h, mul_zero, dotProduct_empty, add_zero,
196
+ zero_mul, neg_zero, empty_val', cons_val_fin_one, cons_val_one, cons_val_zero, lt_neg,
197
+ neg_add_rev, zero_add, le_add_neg_iff_add_le, ← le_neg, abs_neg, true_and]
198
+ refine ⟨?_, Int.ediv_mul_le _ hd, ?_⟩
199
+ · simp only [Int.lt_iff_le_and_ne]
200
+ exact ⟨not_lt.mp h1, A_a_ne_zero h hm⟩
201
+ · rw [mul_comm, add_comm, ← Int.sub_eq_add_neg, ← Int.emod_def,
202
+ abs_eq_self.mpr <| Int.emod_nonneg _ hd]
203
+ exact Int.emod_lt _ hd
204
+
205
+ variable {C : Δ m → Prop }
206
+
207
+ private lemma prop_red_S (hS : ∀ B, C B → C (S • B)) (B) : C (S • B) ↔ C B := by
208
+ refine ⟨?_, hS _⟩
209
+ intro ih
210
+ rw [← (S_smul_four B)]
211
+ solve_by_elim
212
+
213
+ private lemma prop_red_T (hS : ∀ B, C B → C (S • B)) (hT : ∀ B, C B → C (T • B)) (B) :
214
+ C (T • B) ↔ C B := by
215
+ refine ⟨?_, hT _⟩
216
+ intro ih
217
+ rw [show B = T⁻¹ • T • B by simp, ← T_S_rel_smul]
218
+ solve_by_elim (config := {maxDepth := 10 })
219
+
220
+ private lemma prop_red_T_pow (hS : ∀ B, C B → C (S • B)) (hT : ∀ B, C B → C (T • B)) :
221
+ ∀ B (n : ℤ), C (T^n • B) ↔ C B := by
222
+ intro B n
223
+ induction' n using Int.induction_on with n hn m hm
224
+ · simp only [zpow_zero, one_smul, imp_self]
225
+ · simpa only [add_comm (n:ℤ), zpow_add _ 1 , ← smul_eq_mul, zpow_one, smul_assoc, prop_red_T hS hT]
226
+ · rwa [sub_eq_neg_add, zpow_add, zpow_neg_one, ← prop_red_T hS hT, mul_smul, smul_inv_smul]
227
+
228
+ @[elab_as_elim]
229
+ theorem induction_on {C : Δ m → Prop } {A : Δ m} (hm : m ≠ 0 )
230
+ (h0 : ∀ A : Δ m, A.1 1 0 = 0 → 0 < A.1 0 0 → 0 ≤ A.1 0 1 → |(A.1 0 1 )| < |(A.1 1 1 )| → C A)
231
+ (hS : ∀ B, C B → C (S • B)) (hT : ∀ B, C B → C (T • B)) : C A := by
232
+ have h_reduce : C (reduce A) := by
233
+ rcases reduce_mem_reps hm A with ⟨H1, H2, H3, H4⟩
234
+ exact h0 _ H1 H2 H3 H4
235
+ suffices ∀ A : Δ m, C (reduce A) → C A from this _ h_reduce
236
+ apply reduce_rec
237
+ · intro A h
238
+ by_cases h1 : 0 < A.1 0 0
239
+ · simp only [reduce_of_pos h h1, prop_red_T_pow hS hT, imp_self]
240
+ · simp only [reduce_of_not_pos h h1, prop_red_T_pow hS hT, prop_red_S hS, imp_self]
241
+ intro A hc ih hA
242
+ rw [← reduce_reduceStep hc] at hA
243
+ simpa only [reduceStep, prop_red_S hS, prop_red_T_pow hS hT] using ih hA
244
+
245
+ end IntegralFixedDetMatrices
246
+
247
+ end FixedDetMatrices
0 commit comments