Skip to content

Commit c99f041

Browse files
feat(LinearAlgebra/Transvection): the determinant of a transvection is equal to 1. (#32757)
Prove that the determinant of a transvection is equal to 1 The proof goes by showing that the determinant of `LinearMap.transvection f v` is `1 + f v` (even if `f v` is nonzero). I first treat the case of a field, distinguishing whether `f v = 0` (so that we get a transvection) or not (so that we have a dilation). Then, by base change to the field of fractions, I can handle the case of a domain. Finally, the general case is treated by base change from the “universal case” where the base ring is the ring of polynomials in $$2n$$ indeterminates corresponding to the coefficients of $$f$$ and $$v$$. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent c752ef9 commit c99f041

File tree

3 files changed

+273
-7
lines changed

3 files changed

+273
-7
lines changed

Mathlib/LinearAlgebra/Basis/VectorSpace.lean

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public import Mathlib.LinearAlgebra.FreeModule.Basic
99
public import Mathlib.LinearAlgebra.LinearIndependent.Lemmas
1010
public import Mathlib.LinearAlgebra.LinearPMap
1111
public import Mathlib.LinearAlgebra.Projection
12+
public import Mathlib.Tactic.Field
1213

1314
/-!
1415
# Bases in a vector space
@@ -331,3 +332,104 @@ theorem quotient_prod_linearEquiv (p : Submodule K V) : Nonempty (((V ⧸ p) ×
331332
(prodEquivOfIsCompl q p hq.symm)
332333

333334
end DivisionRing
335+
336+
section Field
337+
338+
open Submodule LinearMap Module
339+
340+
variable {K : Type*} {V : Type*} [Field K] [AddCommGroup V] [Module K V]
341+
342+
variable {f : V →ₗ[K] K} {v : V}
343+
344+
/-- In a vector space, given a nonzero linear form `f`,
345+
a nonzero vector `v` such that `f v ≠ 0`,
346+
there exists a basis `b` with an index `i`
347+
such that `v = b i` and `f = (f v) • b.coord i`. -/
348+
theorem exists_basis_of_pairing_ne_zero
349+
(hfv : f v ≠ 0) :
350+
∃ (n : Set V) (b : Module.Basis n K V) (i : n),
351+
v = b i ∧ f = (f v) • b.coord i := by
352+
set b₁ := Basis.ofVectorSpace K (ker f)
353+
set s : Set V := (ker f).subtype '' Set.range b₁
354+
have hs : span K s = ker f := by
355+
simp only [s, span_image]
356+
simp
357+
set n := insert v s
358+
have H₁ : LinearIndepOn K _root_.id n := by
359+
apply LinearIndepOn.id_insert
360+
· apply LinearIndepOn.image
361+
· exact b₁.linearIndependent.linearIndepOn_id
362+
· simp
363+
· simp [hs, hfv]
364+
have H₂ : ⊤ ≤ span K n := by
365+
rintro x -
366+
simp only [n, mem_span_insert']
367+
use -f x / f v
368+
simp only [hs, mem_ker, map_add, map_smul, smul_eq_mul]
369+
field
370+
set b := Basis.mk H₁ (by simpa using H₂)
371+
set i : n := ⟨v, s.mem_insert v⟩
372+
have hi : b i = v := by simp [b, i]
373+
refine ⟨n, b, i, by simp [b, i], ?_⟩
374+
rw [← hi]
375+
apply b.ext
376+
intro j
377+
by_cases h : i = j
378+
· simp [h]
379+
· suffices f (b j) = 0 by
380+
simp [Finsupp.single_eq_of_ne h, this]
381+
rw [← mem_ker, ← hs, Basis.coe_mk]
382+
apply subset_span
383+
apply Or.resolve_left (Set.mem_insert_iff.mpr j.prop)
384+
simp [← hi, b, Subtype.coe_inj, Ne.symm h]
385+
386+
/-- In a vector space, given a nonzero linear form `f`,
387+
a nonzero vector `v` such that `f v = 0`,
388+
there exists a basis `b` with two distinct indices `i`, `j`
389+
such that `v = b i` and `f = b.coord j`. -/
390+
theorem exists_basis_of_pairing_eq_zero
391+
(hfv : f v = 0) (hf : f ≠ 0) (hv : v ≠ 0) :
392+
∃ (n : Set V) (b : Basis n K V) (i j : n),
393+
i ≠ j ∧ v = b i ∧ f = b.coord j := by
394+
lift v to ker f using hfv
395+
have : LinearIndepOn K _root_.id {v} := by simpa using hv
396+
set b₁ : Basis _ K (ker f) := .extend this
397+
obtain ⟨w, hw⟩ : ∃ w, f w = 1 := by
398+
simp only [ne_eq, DFunLike.ext_iff, not_forall] at hf
399+
rcases hf with ⟨w, hw⟩
400+
use (f w)⁻¹ • w
401+
simp_all
402+
set s : Set V := (ker f).subtype '' Set.range b₁
403+
have hs : span K s = ker f := by
404+
simp only [s, span_image]
405+
simp
406+
have hvs : ↑v ∈ s := by
407+
refine ⟨v, ?_, by simp⟩
408+
simp [b₁, this.subset_extend _ _]
409+
set n := insert w s
410+
have H₁ : LinearIndepOn K _root_.id n := by
411+
apply LinearIndepOn.id_insert
412+
· apply LinearIndepOn.image
413+
· exact b₁.linearIndependent.linearIndepOn_id
414+
· simp
415+
· simp [hs, hw]
416+
have H₂ : ⊤ ≤ span K n := by
417+
rintro x -
418+
simp only [n, mem_span_insert']
419+
use -f x
420+
simp [hs, hw]
421+
set b := Basis.mk H₁ (by simpa using H₂)
422+
refine ⟨n, b, ⟨v, by simp [n, hvs]⟩, ⟨w, by simp [n]⟩, ?_, by simp [b], ?_⟩
423+
· apply_fun (f ∘ (↑))
424+
simp [hw]
425+
· apply b.ext
426+
intro i
427+
rw [Basis.coord_apply, Basis.repr_self]
428+
simp only [b, Basis.mk_apply]
429+
rcases i with ⟨x, rfl | ⟨x, hx, rfl⟩⟩
430+
· simp [hw]
431+
· suffices x ≠ w by simp [this]
432+
apply_fun f
433+
simp [hw]
434+
435+
end Field

Mathlib/LinearAlgebra/Determinant.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,13 @@ theorem coe_det [DecidableEq M] :
185185
· congr -- use the correct `DecidableEq` instance
186186
rfl
187187

188+
theorem _root_.Module.Free.of_det_ne_one {f : M →ₗ[R] M} (hf : f.det ≠ 1) :
189+
Module.Free R M := by
190+
by_cases H : ∃ s : Finset M, Nonempty (Module.Basis s R M)
191+
· rcases H with ⟨s, ⟨hs⟩⟩
192+
exact Module.Free.of_basis hs
193+
· classical simp [LinearMap.coe_det, H] at hf
194+
188195
end
189196

190197
-- Auxiliary lemma, the `simp` normal form goes in the other direction

Mathlib/LinearAlgebra/Transvection.lean

Lines changed: 164 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Antoine Chambert-Loir
66

77
module
88

9+
public import Mathlib.LinearAlgebra.Charpoly.BaseChange
910
public import Mathlib.LinearAlgebra.DFinsupp
1011
public import Mathlib.LinearAlgebra.Dual.BaseChange
1112
public import Mathlib.RingTheory.TensorProduct.IsBaseChangeHom
@@ -18,9 +19,14 @@ public import Mathlib.Tactic.Positivity
1819
* When `f : Module.Dual R V` and `v : V`,
1920
`LinearMap.transvection f v` is the linear map given by `x ↦ x + f x • v`,
2021
22+
* `LinearMap.transvection.det` shows that the determinant of
23+
`LinearMap.transvection f v` is equal to `1 + f v`.
24+
2125
* If, moreover, `f v = 0`, then `LinearEquiv.transvection` shows that it is
2226
a linear equivalence.
2327
28+
* `LinearEquiv.transvection.det` shows that it has determinant `1`.
29+
2430
## Note on terminology
2531
2632
In the mathematical litterature, linear maps of the form `LinearMap.transvection f v`
@@ -77,21 +83,21 @@ theorem comp_of_right_eq {f g : Dual R V} {v : V} (hf : f v = 0) :
7783

7884
@[simp]
7985
theorem of_left_eq_zero (v : V) :
80-
transvection (0 : Dual R V) v = LinearMap.id := by
86+
transvection (0 : Dual R V) v = id := by
8187
ext
8288
simp [transvection]
8389

8490
@[simp]
8591
theorem of_right_eq_zero (f : Dual R V) :
86-
transvection f 0 = LinearMap.id := by
92+
transvection f 0 = id := by
8793
ext
8894
simp [transvection]
8995

9096
theorem eq_id_of_finrank_le_one
9197
{R V : Type*} [CommSemiring R] [AddCommMonoid V] [Module R V]
9298
[Free R V] [Module.Finite R V] [StrongRankCondition R]
9399
{f : Dual R V} {v : V} (hfv : f v = 0) (h1 : finrank R V ≤ 1) :
94-
transvection f v = LinearMap.id := by
100+
transvection f v = id := by
95101
interval_cases h : finrank R V
96102
· have : Subsingleton V := (finrank_eq_zero_iff_of_free R V).mp h
97103
simp [Subsingleton.eq_zero v]
@@ -161,24 +167,24 @@ theorem trans_of_right_eq {f g : Dual R V} {v : V}
161167

162168
@[simp]
163169
theorem of_left_eq_zero (v : V) (hv := LinearMap.zero_apply v) :
164-
transvection hv = LinearEquiv.refl R V := by
170+
transvection hv = refl R V := by
165171
ext; simp [transvection]
166172

167173
@[simp]
168174
theorem of_right_eq_zero (f : Dual R V) (hf := f.map_zero) :
169-
transvection hf = LinearEquiv.refl R V := by
175+
transvection hf = refl R V := by
170176
ext; simp [transvection]
171177

172178
theorem symm_eq {f : Dual R V} {v : V}
173179
(hv : f v = 0) (hv' : f (-v) = 0 := by simp [hv]) :
174180
(transvection hv).symm = transvection hv' := by
175181
ext;
176-
simp [LinearEquiv.symm_apply_eq, comp_of_left_eq_apply hv']
182+
simp [symm_apply_eq, comp_of_left_eq_apply hv']
177183

178184
theorem symm_eq' {f : Dual R V} {v : V}
179185
(hf : f v = 0) (hf' : (-f) v = 0 := by simp [hf]) :
180186
(transvection hf).symm = transvection hf' := by
181-
ext; simp [LinearEquiv.symm_apply_eq, comp_of_right_eq_apply hf]
187+
ext; simp [symm_apply_eq, comp_of_right_eq_apply hf]
182188

183189
end LinearEquiv.transvection
184190

@@ -219,3 +225,154 @@ theorem _root_.IsBaseChange.transvection (f : Dual R V) (v : V) :
219225
end LinearMap.transvection
220226

221227
end baseChange
228+
229+
section determinant
230+
231+
namespace LinearMap.transvection
232+
233+
open Polynomial Module
234+
235+
open scoped TensorProduct
236+
237+
section Field
238+
239+
variable {K : Type*} {V : Type*} [Field K] [AddCommGroup V] [Module K V]
240+
241+
variable {f : Dual K V} {v : V}
242+
243+
/-- Determinant of transvections, over a field.
244+
245+
See `LinearMap.Transvection.det` for the general result. -/
246+
private theorem det_ofField [FiniteDimensional K V] (f : Dual K V) (v : V) :
247+
(LinearMap.transvection f v).det = 1 + f v := by
248+
classical
249+
by_cases hfv : f v = 0
250+
· by_cases hv : v = 0
251+
· simp [hv]
252+
by_cases hf : f = 0
253+
· simp [hf]
254+
obtain ⟨ι, b, i, j, hi, hj⟩ := exists_basis_of_pairing_eq_zero hfv hf hv
255+
have : Fintype ι := FiniteDimensional.fintypeBasisIndex b
256+
rw [← det_toMatrix b]
257+
suffices toMatrix b b (LinearMap.transvection f v) = Matrix.transvection i j 1 by
258+
rw [this, Matrix.det_transvection_of_ne i j hi 1, hfv, add_zero]
259+
ext x y
260+
rw [toMatrix_apply, transvection.apply, Matrix.transvection]
261+
simp only [hj.2, Basis.coord_apply, Basis.repr_self, hj.1, map_add, map_smul,
262+
Finsupp.smul_single, smul_eq_mul, mul_one, Finsupp.coe_add, Pi.add_apply, Matrix.add_apply]
263+
apply congr_arg₂
264+
· by_cases h : x = y
265+
· rw [h]; simp
266+
· rw [Finsupp.single_eq_of_ne h, Matrix.one_apply_ne h]
267+
· by_cases h : i = x ∧ j = y
268+
· rw [h.1, h.2]; simp
269+
· rcases not_and_or.mp h with h' | h' <;>
270+
simp [Finsupp.single_eq_of_ne' h',
271+
Finsupp.single_eq_of_ne h',
272+
Matrix.single_apply_of_ne (h := h)]
273+
· obtain ⟨ι, b, i, hv, hf⟩ := exists_basis_of_pairing_ne_zero hfv
274+
have : Fintype ι := FiniteDimensional.fintypeBasisIndex b
275+
rw [← det_toMatrix b]
276+
suffices toMatrix b b (transvection f v) =
277+
Matrix.diagonal (Function.update 1 i (1 + f v)) by
278+
rw [this]
279+
simp only [Matrix.det_diagonal]
280+
rw [Finset.prod_eq_single i]
281+
· simp
282+
· intro j _ hj
283+
simp [Function.update_of_ne hj]
284+
· simp
285+
ext x y
286+
rw [toMatrix_apply, transvection.apply, Matrix.diagonal]
287+
simp only [map_add, Basis.repr_self, map_smul, Finsupp.coe_add, Finsupp.coe_smul,
288+
Pi.add_apply, Pi.smul_apply, smul_eq_mul, Matrix.of_apply]
289+
rw [hv, Function.update_apply, Basis.repr_self, Pi.one_apply, hf]
290+
simp only [smul_apply, Basis.coord_apply, Basis.repr_self, smul_eq_mul,
291+
Finsupp.single_eq_same, mul_one]
292+
split_ifs with hxy hxi
293+
· simp [← hxy, hxi]
294+
· rw [Finsupp.single_eq_of_ne hxi]; simp [hxy]
295+
· rw [Finsupp.single_eq_of_ne hxy, zero_add, mul_assoc]
296+
convert mul_zero _
297+
by_cases hxi : x = i
298+
· simp [← hxi, Finsupp.single_eq_of_ne hxy]
299+
· simp [Finsupp.single_eq_of_ne hxi]
300+
301+
end Field
302+
303+
variable {R V : Type*} [CommRing R] [AddCommGroup V] [Module R V]
304+
305+
/-- Determinant of a transvection, over a domain.
306+
307+
See `LinearMap.transvection.det` for the general case. -/
308+
private theorem det_ofDomain [Free R V] [Module.Finite R V] [IsDomain R]
309+
(f : Dual R V) (v : V) :
310+
(transvection f v).det = 1 + f v := by
311+
let K := FractionRing R
312+
let : Field K := inferInstance
313+
apply FaithfulSMul.algebraMap_injective R K
314+
have := det_ofField (f.baseChange K) (1 ⊗ₜ[R] v)
315+
rw [← transvection.baseChange, det_baseChange,
316+
← algebraMap.coe_one (R := R) (A := K)] at this
317+
simpa [Algebra.algebraMap_eq_smul_one, add_smul] using this
318+
319+
open IsBaseChange
320+
321+
@[simp] theorem det [Free R V] [Module.Finite R V]
322+
(f : Dual R V) (v : V) :
323+
(transvection f v).det = 1 + f v := by
324+
rcases subsingleton_or_nontrivial R with hR | hR
325+
· subsingleton
326+
let b := finBasis R V
327+
set n := finrank R V
328+
let S := MvPolynomial (Fin n ⊕ Fin n) ℤ
329+
let γ : S →+* R :=
330+
(MvPolynomial.aeval (Sum.elim (fun i ↦ f (b i)) (fun i ↦ b.coord i v)) :
331+
MvPolynomial (Fin n ⊕ Fin n) ℤ →ₐ[ℤ] R)
332+
have : IsDomain S := inferInstance
333+
let _ : Algebra S R := RingHom.toAlgebra γ
334+
let _ : Module S V := compHom V γ
335+
have _ : IsScalarTower S R V := IsScalarTower.of_compHom S R V
336+
have ibc := IsBaseChange.of_fintype_basis S b
337+
set ε := Fintype.linearCombination S (fun i ↦ b i)
338+
set M := Fin n → S
339+
have hε (i) : ε (Pi.single i 1) = b i := by
340+
rw [Fintype.linearCombination_apply_single, one_smul]
341+
let fM : Dual S M :=
342+
Fintype.linearCombination S fun i ↦ MvPolynomial.X (Sum.inl i)
343+
let vM : M := fun i ↦ MvPolynomial.X (Sum.inr i)
344+
have hf : ibc.toDual fM = f := by
345+
apply b.ext
346+
intro i
347+
rw [← hε, toDual_comp_apply, Fintype.linearCombination_apply_single,
348+
one_smul, RingHom.algebraMap_toAlgebra, hε]
349+
apply MvPolynomial.aeval_X
350+
have hv : ε vM = v := by
351+
rw [of_fintype_basis_eq]
352+
ext i
353+
rw [RingHom.algebraMap_toAlgebra]
354+
simp only [vM, γ, Function.comp_apply]
355+
apply MvPolynomial.aeval_X
356+
rw [← hf, ← hv, ← IsBaseChange.transvection, det_endHom, det_ofDomain]
357+
rw [map_add, map_one, add_right_inj, toDual_comp_apply]
358+
359+
/-- Determinant of a transvection.
360+
361+
It is not necessary to assume that the module is finite and free
362+
because `LinearMap.det` is identically 1 otherwise. -/
363+
@[simp] theorem _root_.LinearEquiv.det_eq_one
364+
{f : Dual R V} {v : V} (hfv : f v = 0) :
365+
(LinearEquiv.transvection hfv).det = 1 := by
366+
rw [← Units.val_inj, LinearEquiv.coe_det,
367+
LinearEquiv.transvection.coe_toLinearMap hfv, Units.val_one]
368+
by_contra! h
369+
have : Free R V := Free.of_det_ne_one h
370+
have : Module.Finite R V := finite_of_det_ne_one h
371+
apply h
372+
rw [transvection.det, hfv, add_zero]
373+
374+
end transvection
375+
376+
end LinearMap
377+
378+
end determinant

0 commit comments

Comments
 (0)