Skip to content

Commit 47ad337

Browse files
AntoineChambert-Loirpre-commit-ci-lite[bot]
authored andcommitted
feat(LinearAlgebra/Transvection): auxiliary lemmas to compute the determinant of transvection in a module (leanprover-community#31138)
Auxiliary results towards the proof that the determinant of a transvection is equal to 1. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent b7257a7 commit 47ad337

File tree

7 files changed

+242
-30
lines changed

7 files changed

+242
-30
lines changed

Mathlib/LinearAlgebra/Determinant.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,13 @@ lemma isUnit_iff_isUnit_det [Module.Finite R M] [Module.Free R M] (f : M →ₗ[
312312
let b := Module.Free.chooseBasis R M
313313
rw [← isUnit_toMatrix_iff b, ← det_toMatrix b, Matrix.isUnit_iff_isUnit_det (toMatrix b b f)]
314314

315+
/-- If a linear map has determinant different from `1`, then the module is free. -/
316+
theorem free_of_det_ne_one {f : M →ₗ[R] M} (hf : f.det ≠ 1) : Module.Free R M := by
317+
by_cases H : ∃ s : Finset M, Nonempty (Basis s R M)
318+
· rcases H with ⟨s, ⟨hs⟩⟩
319+
exact Module.Free.of_basis hs
320+
· classical simp [LinearMap.coe_det, H] at hf
321+
315322
/-- If a linear map has determinant different from `1`, then the space is finite-dimensional. -/
316323
theorem finite_of_det_ne_one {f : M →ₗ[R] M} (hf : f.det ≠ 1) : Module.Finite R M := by
317324
by_cases H : ∃ s : Finset M, Nonempty (Basis s R M)

Mathlib/LinearAlgebra/DirectSum/Finsupp.lean

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,28 @@ lemma finsuppScalarRight_symm_apply_single (i : ι) (m : M) :
237237
m ⊗ₜ[R] (Finsupp.single i 1) := by
238238
simp [finsuppScalarRight, finsuppRight_symm_apply_single]
239239

240+
theorem finsuppScalarRight_smul (s : S) (t) :
241+
finsuppScalarRight R M ι (s • t) = s • finsuppScalarRight R M ι t := by
242+
induction t using TensorProduct.induction_on with
243+
| zero => simp
244+
| add x y hx hy => simp [hx, hy]
245+
| tmul m x =>
246+
simp only [smul_tmul', finsuppScalarRight_apply_tmul, Finsupp.smul_sum]
247+
congr
248+
ext i n j
249+
simp [smul_comm n s m]
250+
251+
variable (R S M ι) in
252+
/-- When `M` is also an `S`-module, `TensorProduct.finsuppScalarRight R M ι` is `S`-linear. -/
253+
noncomputable def finsuppScalarRight' :
254+
M ⊗[R] (ι →₀ R) ≃ₗ[S] ι →₀ M where
255+
toAddEquiv := finsuppScalarRight R M ι
256+
map_smul' s x := finsuppScalarRight_smul s x
257+
258+
theorem coe_finsuppScalarRight' :
259+
⇑(finsuppScalarRight' R M ι S) = finsuppScalarRight R M ι :=
260+
rfl
261+
240262
end TensorProduct
241263

242264
end TensorProduct

Mathlib/LinearAlgebra/Finsupp/LinearCombination.lean

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ theorem range_linearCombination : LinearMap.range (linearCombination R v) = span
136136
use single i 1
137137
simp [hi]
138138

139+
theorem _root_.span_range_eq_top_iff_surjective_finsuppLinearCombination :
140+
Submodule.span R (Set.range v) = ⊤ ↔
141+
Function.Surjective (Finsupp.linearCombination R v) := by
142+
rw [← LinearMap.range_eq_top, range_linearCombination]
143+
139144
theorem lmapDomain_linearCombination (f : α → α') (g : M →ₗ[R] M') (h : ∀ i, g (v i) = v' (f i)) :
140145
(linearCombination R v').comp (lmapDomain R R f) = g.comp (linearCombination R v) := by
141146
ext l
@@ -340,6 +345,11 @@ theorem Fintype.range_linearCombination :
340345
rw [← Finsupp.linearCombination_eq_fintype_linearCombination, LinearMap.range_comp,
341346
LinearEquiv.range, Submodule.map_top, Finsupp.range_linearCombination]
342347

348+
theorem span_range_eq_top_iff_surjective_fintypeLinearCombination :
349+
Submodule.span R (Set.range v) = ⊤ ↔
350+
Function.Surjective (Fintype.linearCombination R v) := by
351+
rw [← LinearMap.range_eq_top, Fintype.range_linearCombination]
352+
343353
/-- `Fintype.bilinearCombination R S v f` is the linear combination of vectors in `v` with weights
344354
in `f`. This variant of `Finsupp.linearCombination` is defined on fintype indexed vectors.
345355

Mathlib/LinearAlgebra/SpecialLinearGroup.lean

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ theorem det_eq_one (u : SpecialLinearGroup R V) :
5757
LinearMap.det (u : V →ₗ[R] V) = 1 := by
5858
simp [← LinearEquiv.coe_det, u.prop]
5959

60+
/-- The coercion from `SpecialLinearGroup R V` to the function type `V → V` -/
6061
instance : CoeFun (SpecialLinearGroup R V) (fun _ ↦ V → V) where
6162
coe u x := u.val x
6263

@@ -69,6 +70,7 @@ theorem ext (u v : SpecialLinearGroup R V) : (∀ x, u x = v x) → u = v :=
6970

7071
section rankOne
7172

73+
/-- If a free module has `Module.finrank` equal to `1`, then its special linear group is trivial. -/
7274
theorem subsingleton_of_finrank_eq_one [Module.Free R V] (d1 : Module.finrank R V = 1) :
7375
Subsingleton (SpecialLinearGroup R V) where
7476
allEq u v := by
@@ -167,6 +169,7 @@ theorem coe_dualMap
167169

168170
end CoeLemmas
169171

172+
/-- The special linear group of a module is a group. -/
170173
instance : Group (SpecialLinearGroup R V) := fast_instance%
171174
Function.Injective.group _ Subtype.coe_injective coe_one coe_mul coe_inv coe_div coe_pow coe_zpow
172175

@@ -176,18 +179,21 @@ def toLinearEquiv : SpecialLinearGroup R V →* V ≃ₗ[R] V where
176179
map_one' := coe_one
177180
map_mul' := coe_mul
178181

179-
theorem toLinearEquiv_apply (A : SpecialLinearGroup R V) (v : V) :
182+
@[simp] lemma toLinearEquiv_apply (A : SpecialLinearGroup R V) (v : V) :
180183
A.toLinearEquiv v = A v :=
181184
rfl
182185

186+
@[simp]
183187
theorem toLinearEquiv_to_linearMap (A : SpecialLinearGroup R V) :
184188
(SpecialLinearGroup.toLinearEquiv A) = (A : V →ₗ[R] V) :=
185189
rfl
186190

191+
@[simp]
187192
theorem toLinearEquiv_symm_apply (A : SpecialLinearGroup R V) (v : V) :
188193
A.toLinearEquiv.symm v = A⁻¹ v :=
189194
rfl
190195

196+
@[simp]
191197
theorem toLinearEquiv_symm_to_linearMap (A : SpecialLinearGroup R V) :
192198
A.toLinearEquiv.symm = ((A⁻¹ : SpecialLinearGroup R V) : V →ₗ[R] V) :=
193199
rfl

Mathlib/LinearAlgebra/Transvection.lean

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@ Copyright (c) 2025 Antoine Chambert-Loir. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Antoine Chambert-Loir
55
-/
6+
67
module
78

9+
public import Mathlib.LinearAlgebra.Charpoly.BaseChange
810
public import Mathlib.LinearAlgebra.DFinsupp
911
public import Mathlib.LinearAlgebra.Dual.BaseChange
1012
public import Mathlib.RingTheory.TensorProduct.IsBaseChangeHom
13+
public import Mathlib.RingTheory.TensorProduct.IsBaseChangePi
1114

1215
/-!
1316
# Transvections in a module
@@ -16,62 +19,93 @@ public import Mathlib.RingTheory.TensorProduct.IsBaseChangeHom
1619
`LinearMap.transvection f v` is the linear map given by `x ↦ x + f x • v`,
1720
1821
* If, moreover, `f v = 0`, then `LinearEquiv.transvection` shows that it is
19-
a linear equivalence.
22+
a linear equivalence.
23+
24+
## Note on terminology
25+
26+
In the mathematical litterature, linear maps of the form `LinearMap.transvection f v`
27+
are only called “transvections” when `f v = 0`. Otherwise, they are sometimes
28+
called “dilations” (especially if `f v ≠ -1`).
29+
30+
The definition is almost the same as that of `Module.preReflection f v`,
31+
up to a sign change, which are interesting when `f v = 2`, because they give “reflections”.
2032
2133
-/
2234

2335
@[expose] public section
2436

2537
namespace LinearMap
2638

39+
open Module
40+
2741
variable {R V : Type*} [CommSemiring R] [AddCommMonoid V] [Module R V]
2842

2943
/-- The transvection associated with a linear form `f` and a vector `v`.
3044
31-
NB. It is only a transvection when `f v = 0`. See also `Module.preReflection`. -/
32-
def transvection (f : Module.Dual R V) (v : V) : V →ₗ[R] V where
45+
NB. In mathematics, these linear maps are only called “transvections” when `f v = 0`.
46+
See also `Module.preReflection` for a similar definition, up to a sign. -/
47+
def transvection (f : Dual R V) (v : V) : V →ₗ[R] V where
3348
toFun x := x + f x • v
3449
map_add' x y := by simp only [map_add]; module
3550
map_smul' r x := by simp only [map_smul, RingHom.id_apply, smul_eq_mul]; module
3651

3752
namespace transvection
3853

39-
theorem apply (f : Module.Dual R V) (v x : V) :
54+
theorem apply (f : Dual R V) (v x : V) :
4055
transvection f v x = x + f x • v :=
4156
rfl
4257

43-
theorem comp_of_left_eq_apply {f : Module.Dual R V} {v w : V} {x : V} (hw : f w = 0) :
58+
theorem comp_of_left_eq_apply {f : Dual R V} {v w : V} {x : V} (hw : f w = 0) :
4459
transvection f v (transvection f w x) = transvection f (v + w) x := by
4560
simp only [transvection, coe_mk, AddHom.coe_mk, map_add, map_smul, hw, smul_add]
4661
module
4762

48-
theorem comp_of_left_eq {f : Module.Dual R V} {v w : V} (hw : f w = 0) :
63+
theorem comp_of_left_eq {f : Dual R V} {v w : V} (hw : f w = 0) :
4964
(transvection f v) ∘ₗ (transvection f w) = transvection f (v + w) := by
5065
ext; simp [comp_of_left_eq_apply hw]
5166

52-
theorem comp_of_right_eq_apply {f g : Module.Dual R V} {v : V} {x : V} (hf : f v = 0) :
67+
theorem comp_of_right_eq_apply {f g : Dual R V} {v : V} {x : V} (hf : f v = 0) :
5368
(transvection f v) (transvection g v x) = transvection (f + g) v x := by
5469
simp only [transvection, coe_mk, AddHom.coe_mk, map_add, map_smul, hf, add_apply]
5570
module
5671

57-
theorem comp_of_right_eq {f g : Module.Dual R V} {v : V} (hf : f v = 0) :
72+
theorem comp_of_right_eq {f g : Dual R V} {v : V} (hf : f v = 0) :
5873
(transvection f v) ∘ₗ (transvection g v) = transvection (f + g) v := by
5974
ext; simp [comp_of_right_eq_apply hf]
6075

6176
@[simp]
6277
theorem of_left_eq_zero (v : V) :
63-
transvection (0 : Module.Dual R V) v = LinearMap.id := by
78+
transvection (0 : Dual R V) v = LinearMap.id := by
6479
ext
6580
simp [transvection]
6681

6782
@[simp]
68-
theorem of_right_eq_zero (f : Module.Dual R V) :
83+
theorem of_right_eq_zero (f : Dual R V) :
6984
transvection f 0 = LinearMap.id := by
7085
ext
7186
simp [transvection]
7287

88+
theorem eq_id_of_finrank_le_one
89+
[Free R V] [Module.Finite R V] [StrongRankCondition R]
90+
{f : Dual R V} {v : V} (hfv : f v = 0) (h1 : finrank R V ≤ 1) :
91+
transvection f v = LinearMap.id := by
92+
let b := finBasis R V
93+
rcases (by lia : finrank R V = 0 ∨ finrank R V = 1) with h0 | h1
94+
· have : Subsingleton V := (finrank_eq_zero_iff_of_free R V).mp h0
95+
simp [Subsingleton.eq_zero v]
96+
· ext x
97+
suffices f x • v = 0 by
98+
simp [apply, this]
99+
let i : Fin (finrank R V) := ⟨0, by simp [h1]⟩
100+
suffices ∀ x, x = b.repr x i • (b i) by
101+
rw [this v, map_smul, smul_eq_mul, mul_comm] at hfv
102+
rw [this x, this v, map_smul, smul_eq_mul, ← mul_smul, mul_assoc, hfv, mul_zero, zero_smul]
103+
intro x
104+
have : x = ∑ i, b.repr x i • b i := (Basis.sum_equivFun b x).symm
105+
rwa [Finset.sum_eq_single_of_mem i (Finset.mem_univ i) (by grind)] at this
106+
73107
theorem congr {W : Type*} [AddCommMonoid W] [Module R W]
74-
(f : Module.Dual R V) (v : V) (e : V ≃ₗ[R] W) :
108+
(f : Dual R V) (v : V) (e : V ≃ₗ[R] W) :
75109
e ∘ₗ (transvection f v) ∘ₗ e.symm = transvection (f ∘ₗ e.symm) (e v) := by
76110
ext; simp [transvection.apply]
77111

@@ -81,10 +115,10 @@ variable {R V : Type*} [CommRing R] [AddCommGroup V] [Module R V]
81115

82116
namespace LinearEquiv
83117

84-
open LinearMap LinearMap.transvection
118+
open LinearMap LinearMap.transvection Module
85119

86120
/-- The transvection associated with a linear form `f` and a vector `v` such that `f v = 0`. -/
87-
def transvection {f : Module.Dual R V} {v : V} (h : f v = 0) :
121+
def transvection {f : Dual R V} {v : V} (h : f v = 0) :
88122
V ≃ₗ[R] V where
89123
toFun := LinearMap.transvection f v
90124
invFun := LinearMap.transvection f (-v)
@@ -98,26 +132,26 @@ def transvection {f : Module.Dual R V} {v : V} (h : f v = 0) :
98132

99133
namespace transvection
100134

101-
theorem apply {f : Module.Dual R V} {v : V} (h : f v = 0) (x : V) :
135+
theorem apply {f : Dual R V} {v : V} (h : f v = 0) (x : V) :
102136
transvection h x = x + f x • v :=
103137
rfl
104138

105139
@[simp]
106-
theorem coe_toLinearMap {f : Module.Dual R V} {v : V} (h : f v = 0) :
140+
theorem coe_toLinearMap {f : Dual R V} {v : V} (h : f v = 0) :
107141
LinearEquiv.transvection h = LinearMap.transvection f v :=
108142
rfl
109143

110144
@[simp]
111-
theorem coe_apply {f : Module.Dual R V} {v x : V} {h : f v = 0} :
145+
theorem coe_apply {f : Dual R V} {v x : V} {h : f v = 0} :
112146
LinearEquiv.transvection h x = LinearMap.transvection f v x :=
113147
rfl
114148

115-
theorem trans_of_left_eq {f : Module.Dual R V} {v w : V}
149+
theorem trans_of_left_eq {f : Dual R V} {v w : V}
116150
(hv : f v = 0) (hw : f w = 0) (hvw : f (v + w) = 0 := by simp [hv, hw]) :
117151
(transvection hw).trans (transvection hv) = transvection hvw := by
118152
ext; simp [comp_of_left_eq_apply hw]
119153

120-
theorem trans_of_right_eq {f g : Module.Dual R V} {v : V}
154+
theorem trans_of_right_eq {f g : Dual R V} {v : V}
121155
(hf : f v = 0) (hg : g v = 0) (hfg : (f + g) v = 0 := by simp [hf, hg]) :
122156
(transvection hg).trans (transvection hf) = transvection hfg := by
123157
ext; simp [comp_of_right_eq_apply hf]
@@ -128,17 +162,17 @@ theorem of_left_eq_zero (v : V) (hv := LinearMap.zero_apply v) :
128162
ext; simp [transvection]
129163

130164
@[simp]
131-
theorem of_right_eq_zero (f : Module.Dual R V) (hf := f.map_zero) :
165+
theorem of_right_eq_zero (f : Dual R V) (hf := f.map_zero) :
132166
transvection hf = LinearEquiv.refl R V := by
133167
ext; simp [transvection]
134168

135-
theorem symm_eq {f : Module.Dual R V} {v : V}
169+
theorem symm_eq {f : Dual R V} {v : V}
136170
(hv : f v = 0) (hv' : f (-v) = 0 := by simp [hv]) :
137171
(transvection hv).symm = transvection hv' := by
138172
ext;
139173
simp [LinearEquiv.symm_apply_eq, comp_of_left_eq_apply hv']
140174

141-
theorem symm_eq' {f : Module.Dual R V} {v : V}
175+
theorem symm_eq' {f : Dual R V} {v : V}
142176
(hf : f v = 0) (hf' : (-f) v = 0 := by simp [hf]) :
143177
(transvection hf).symm = transvection hf' := by
144178
ext; simp [LinearEquiv.symm_apply_eq, comp_of_right_eq_apply hf]
@@ -149,16 +183,16 @@ section baseChange
149183

150184
namespace LinearMap.transvection
151185

152-
open LinearMap LinearEquiv
186+
open LinearMap LinearEquiv Module
153187

154188
variable {A : Type*} [CommRing A] [Algebra R A]
155189

156-
theorem baseChange (f : Module.Dual R V) (v : V) :
190+
theorem baseChange (f : Dual R V) (v : V) :
157191
(transvection f v).baseChange A = transvection (f.baseChange A) (1 ⊗ₜ[R] v) := by
158192
ext; simp [transvection, TensorProduct.tmul_add]
159193

160194
theorem _root_.LinearEquiv.transvection.baseChange
161-
{f : Module.Dual R V} {v : V} (h : f v = 0)
195+
{f : Dual R V} {v : V} (h : f v = 0)
162196
(hA : f.baseChange A (1 ⊗ₜ[R] v) = 0 := by simp [Algebra.algebraMap_eq_smul_one]) :
163197
(LinearEquiv.transvection h).baseChange R A V V = LinearEquiv.transvection hA := by
164198
simp [← toLinearMap_inj, transvection.coe_toLinearMap, transvection.baseChange]
@@ -169,7 +203,7 @@ variable {W : Type*} [AddCommMonoid W] [Module R W] [Module A W]
169203
[IsScalarTower R A W] {ε : V →ₗ[R] W} (ibc : IsBaseChange A ε)
170204

171205
@[simp]
172-
theorem _root_.IsBaseChange.transvection (f : Module.Dual R V) (v : V) :
206+
theorem _root_.IsBaseChange.transvection (f : Dual R V) (v : V) :
173207
ibc.endHom (transvection f v) = transvection (ibc.toDual f) (ε v) := by
174208
ext w
175209
induction w using ibc.inductionOn with

0 commit comments

Comments
 (0)