Skip to content

Commit 984810d

Browse files
feat(LinearAlgebra/SpecialLinearGroup): special linear group of a module (#30987)
Define the special linear group of a module. Relate it with `Matrix.SpecialLinearGroup`. Several additional constructions. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 41c8cd5 commit 984810d

File tree

10 files changed

+500
-15
lines changed

10 files changed

+500
-15
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4552,6 +4552,7 @@ import Mathlib.LinearAlgebra.SesquilinearForm.Basic
45524552
import Mathlib.LinearAlgebra.SesquilinearForm.Star
45534553
import Mathlib.LinearAlgebra.Span.Basic
45544554
import Mathlib.LinearAlgebra.Span.Defs
4555+
import Mathlib.LinearAlgebra.SpecialLinearGroup
45554556
import Mathlib.LinearAlgebra.StdBasis
45564557
import Mathlib.LinearAlgebra.SymmetricAlgebra.Basic
45574558
import Mathlib.LinearAlgebra.SymmetricAlgebra.Basis

Mathlib/LinearAlgebra/Charpoly/BaseChange.lean

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ Authors: Andrew Yang
66
import Mathlib.LinearAlgebra.Charpoly.ToMatrix
77
import Mathlib.LinearAlgebra.Determinant
88
import Mathlib.RingTheory.TensorProduct.Finite
9+
import Mathlib.LinearAlgebra.TensorProduct.Tower
910

1011

1112
/-! # The characteristic polynomial of base change -/
1213

13-
@[simp]
14-
lemma LinearMap.charpoly_baseChange {R M} [CommRing R] [AddCommGroup M] [Module R M]
14+
variable {R M} [CommRing R] [AddCommGroup M] [Module R M]
1515
[Module.Free R M] [Module.Finite R M] (f : M →ₗ[R] M)
16-
(A) [CommRing A] [Algebra R A] :
16+
(A) [CommRing A] [Algebra R A]
17+
18+
@[simp]
19+
lemma LinearMap.charpoly_baseChange :
1720
(f.baseChange A).charpoly = f.charpoly.map (algebraMap R A) := by
1821
nontriviality A
1922
have := (algebraMap R A).domain_nontrivial
@@ -25,20 +28,23 @@ lemma LinearMap.charpoly_baseChange {R M} [CommRing R] [AddCommGroup M] [Module
2528
ext i j
2629
simp [LinearMap.toMatrix_apply, ← Algebra.algebraMap_eq_smul_one]
2730

28-
lemma LinearMap.det_eq_sign_charpoly_coeff {R M} [CommRing R] [AddCommGroup M] [Module R M]
29-
[Module.Free R M] [Module.Finite R M] (f : M →ₗ[R] M) :
31+
lemma LinearMap.det_eq_sign_charpoly_coeff :
3032
LinearMap.det f = (-1) ^ Module.finrank R M * f.charpoly.coeff 0 := by
3133
nontriviality R
3234
rw [← LinearMap.det_toMatrix (Module.Free.chooseBasis R M), Matrix.det_eq_sign_charpoly_coeff,
3335
← Module.finrank_eq_card_chooseBasisIndex, charpoly_def]
3436

35-
lemma LinearMap.det_baseChange {R M} [CommRing R] [AddCommGroup M] [Module R M]
36-
[Module.Free R M] [Module.Finite R M]
37-
{A} [CommRing A] [Algebra R A] (f : M →ₗ[R] M) :
37+
variable {A} in
38+
lemma LinearMap.det_baseChange :
3839
LinearMap.det (f.baseChange A) = algebraMap R A (LinearMap.det f) := by
3940
nontriviality A
4041
have := (algebraMap R A).domain_nontrivial
4142
rw [LinearMap.det_eq_sign_charpoly_coeff, LinearMap.det_eq_sign_charpoly_coeff]
4243
simp
4344

45+
lemma LinearEquiv.det_baseChange (f : M ≃ₗ[R] M) :
46+
LinearEquiv.det (f.baseChange R A _ _) = (LinearEquiv.det f).map (algebraMap R A) := by
47+
ext
48+
simp [LinearMap.det_baseChange]
49+
4450
/-! Also see `LinearMap.trace_baseChange` in `Mathlib/LinearAlgebra/Trace` -/

Mathlib/LinearAlgebra/Determinant.lean

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ import Mathlib.LinearAlgebra.FreeModule.StrongRankCondition
77
import Mathlib.LinearAlgebra.GeneralLinearGroup
88
import Mathlib.LinearAlgebra.Matrix.Reindex
99
import Mathlib.Tactic.FieldSimp
10+
import Mathlib.LinearAlgebra.Dual.Basis
11+
import Mathlib.LinearAlgebra.Matrix.Dual
1012
import Mathlib.LinearAlgebra.Matrix.NonsingularInverse
1113
import Mathlib.LinearAlgebra.Matrix.Basis
1214
import Mathlib.LinearAlgebra.Matrix.ToLinearEquiv
13-
15+
import Mathlib.RingTheory.Finiteness.Cardinality
1416
/-!
1517
# Determinant of families of vectors
1618
@@ -486,6 +488,35 @@ theorem LinearEquiv.coe_ofIsUnitDet {f : M →ₗ[R] M'} {v : Basis ι R M} {v'
486488
ext x
487489
rfl
488490

491+
/-- Builds a linear equivalence from an endomorphism whose determinant is a unit. -/
492+
noncomputable def LinearMap.equivOfIsUnitDet
493+
[Module.Free R M] [Module.Finite R M]
494+
{f : M →ₗ[R] M} (h : IsUnit f.det) :
495+
M ≃ₗ[R] M := by
496+
by_cases hR : Nontrivial R
497+
· let ⟨ι, b⟩ := (Module.Free.exists_basis R M).some
498+
have : Finite ι := Module.Finite.finite_basis b
499+
have : Fintype ι := Fintype.ofFinite ι
500+
have : DecidableEq ι := Classical.typeDecidableEq ι
501+
exact LinearEquiv.ofIsUnitDet (by rwa [det_toMatrix b])
502+
· exact 1
503+
504+
@[simp]
505+
theorem LinearMap.equivOfIsUnitDet_apply
506+
[Module.Free R M] [Module.Finite R M]
507+
{f : M →ₗ[R] M} (h : IsUnit f.det) (x : M) :
508+
(LinearMap.equivOfIsUnitDet h) x = f x := by
509+
nontriviality M
510+
simp [equivOfIsUnitDet, dif_pos (Module.nontrivial R M)]
511+
512+
@[simp]
513+
theorem LinearMap.coe_equivOfIsUnitDet
514+
[Module.Free R M] [Module.Finite R M]
515+
{f : M →ₗ[R] M} (h : IsUnit f.det) :
516+
(LinearMap.equivOfIsUnitDet h : M →ₗ[R] M) = f := by
517+
ext
518+
apply LinearMap.equivOfIsUnitDet_apply
519+
489520
/-- Builds a linear equivalence from a linear map on a finite-dimensional vector space whose
490521
determinant is nonzero. -/
491522
abbrev LinearMap.equivOfDetNeZero {𝕜 : Type*} [Field 𝕜] {M : Type*} [AddCommGroup M] [Module 𝕜 M]
@@ -705,3 +736,17 @@ theorem det_isUnitSMul {w : ι → R} (hw : ∀ i, IsUnit (w i)) :
705736
e.det_unitsSMul_self _
706737

707738
end Module.Basis
739+
740+
section Dual
741+
742+
/-- The determinant of the transpose of an endomorphism coincides with its determinant. -/
743+
theorem _root_.LinearMap.det_dualMap
744+
[Module.Free R M] [Module.Finite R M] (f : M →ₗ[R] M) :
745+
f.dualMap.det = f.det := by
746+
set b := Module.Free.chooseBasis R M
747+
have : Fintype (Module.Free.ChooseBasisIndex R M) :=
748+
Module.Free.ChooseBasisIndex.fintype R M
749+
rw [← LinearMap.det_toMatrix b, ← LinearMap.det_toMatrix b.dualBasis]
750+
simp [LinearMap.dualMap_def, LinearMap.toMatrix_transpose]
751+
752+
end Dual

Mathlib/LinearAlgebra/Dimension/Free.lean

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,24 @@ noncomputable def basisUnique (ι : Type*) [Unique ι]
242242
Module.finite_of_finrank_pos (_root_.zero_lt_one.trans_le h.symm.le)
243243
(finBasisOfFinrankEq R M h).reindex (Equiv.ofUnique _ _)
244244

245+
/-- If a finite module of `finrank 1` has a basis, then this basis has a unique element. -/
246+
theorem Basis.nonempty_unique_index_of_finrank_eq_one
247+
{ι : Type*} (b : Module.Basis ι R M) (d1 : Module.finrank R M = 1) :
248+
Nonempty (Unique ι) := by
249+
-- why isn't this an instance?
250+
have : Nontrivial R := nontrivial_of_invariantBasisNumber R
251+
haveI : Module.Finite R M :=
252+
Module.finite_of_finrank_pos (Nat.lt_of_sub_eq_succ d1)
253+
have : Finite ι := Module.Finite.finite_basis b
254+
have : Fintype ι := Fintype.ofFinite ι
255+
rwa [Module.finrank_eq_card_basis b, Fintype.card_eq_one_iff_nonempty_unique] at d1
256+
257+
theorem nonempty_linearEquiv_of_finrank_eq_one (d1 : Module.finrank R M = 1) :
258+
Nonempty (R ≃ₗ[R] M) := by
259+
let ⟨ι, b⟩ := (Module.Free.exists_basis R M).some
260+
have : Unique ι := (b.nonempty_unique_index_of_finrank_eq_one d1).some
261+
exact ⟨((b.equivFun).trans (LinearEquiv.funUnique ι R R)).symm⟩
262+
245263
@[simp]
246264
theorem basisUnique_repr_eq_zero_iff {ι : Type*} [Unique ι]
247265
{h : finrank R M = 1} {v : M} {i : ι} :
@@ -250,6 +268,38 @@ theorem basisUnique_repr_eq_zero_iff {ι : Type*} [Unique ι]
250268
(basisUnique ι h).repr.map_eq_zero_iff.mp (Finsupp.ext fun j => Subsingleton.elim i j ▸ hv),
251269
fun hv => by rw [hv, LinearEquiv.map_zero, Finsupp.zero_apply]⟩
252270

271+
variable {R : Type*} [CommSemiring R] [StrongRankCondition R]
272+
{M : Type*} [AddCommMonoid M] [Module R M] [Module.Free R M]
273+
274+
theorem _root_.LinearMap.existsUnique_eq_smul_id_of_finrank_eq_one
275+
(d1 : Module.finrank R M = 1) (u : M →ₗ[R] M) :
276+
∃! c : R, u = c • LinearMap.id := by
277+
let e := (nonempty_linearEquiv_of_finrank_eq_one d1).some
278+
set c := e.symm (u (e 1)) with hc
279+
suffices u = c • LinearMap.id by
280+
use c
281+
simp only [this, true_and]
282+
intro d hcd
283+
rw [LinearMap.ext_iff] at hcd
284+
simpa using (LinearEquiv.congr_arg (e := e.symm) (hcd (e 1))).symm
285+
ext x
286+
have (x : M) : x = (e.symm x) • (e 1) := by simp [← LinearEquiv.map_smul]
287+
rw [this x]
288+
simp only [hc, map_smul, LinearMap.smul_apply, LinearMap.id_coe, id_eq]
289+
rw [← this]
290+
291+
/-- Endomorphisms of a free module of rank one are homotheties. -/
292+
@[simps apply]
293+
noncomputable def _root_.LinearEquiv.smul_id_of_finrank_eq_one (d1 : Module.finrank R M = 1) :
294+
R ≃ₗ[R] (M →ₗ[R] M) where
295+
toFun := fun c ↦ c • LinearMap.id
296+
map_add' c d := by ext; simp [add_smul]
297+
map_smul' c d := by ext; simp [mul_smul]
298+
invFun u := (u.existsUnique_eq_smul_id_of_finrank_eq_one d1).choose
299+
left_inv c := by
300+
simp [← (LinearMap.existsUnique_eq_smul_id_of_finrank_eq_one d1 _).choose_spec.2 c]
301+
right_inv u := ((u.existsUnique_eq_smul_id_of_finrank_eq_one d1).choose_spec.1).symm
302+
253303
end Module
254304

255305
namespace Algebra

Mathlib/LinearAlgebra/Dimension/FreeAndStrongRankCondition.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ theorem Module.rank_le_one_iff_top_isPrincipal [Module.Free K V] :
170170
rw [← Submodule.rank_le_one_iff_isPrincipal, rank_top]
171171

172172
/-- A module has dimension 1 iff there is some `v : V` so `{v}` is a basis.
173-
-/
173+
174+
See also `Module.Basis.nonempty_unique_index_of_finrank_eq_one` -/
174175
theorem finrank_eq_one_iff [Module.Free K V] (ι : Type*) [Unique ι] :
175176
finrank K V = 1 ↔ Nonempty (Basis ι K V) := by
176177
constructor

Mathlib/LinearAlgebra/GeneralLinearGroup.lean

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ def toLinearEquiv (f : GeneralLinearGroup R M) : M ≃ₗ[R] M :=
4343
@[simp] lemma coe_toLinearEquiv (f : GeneralLinearGroup R M) :
4444
f.toLinearEquiv = (f : M → M) := rfl
4545

46+
theorem toLinearEquiv_mul (f g : GeneralLinearGroup R M) :
47+
(f * g).toLinearEquiv = f.toLinearEquiv * g.toLinearEquiv := by
48+
rfl
49+
50+
theorem toLinearEquiv_inv (f : GeneralLinearGroup R M) :
51+
(f⁻¹).toLinearEquiv = (f.toLinearEquiv)⁻¹ := by
52+
rfl
53+
4654
/-- An equivalence from `M` to itself determines an invertible linear map. -/
4755
def ofLinearEquiv (f : M ≃ₗ[R] M) : GeneralLinearGroup R M where
4856
val := f
@@ -53,6 +61,14 @@ def ofLinearEquiv (f : M ≃ₗ[R] M) : GeneralLinearGroup R M where
5361
@[simp] lemma coe_ofLinearEquiv (f : M ≃ₗ[R] M) :
5462
ofLinearEquiv f = (f : M → M) := rfl
5563

64+
theorem ofLinearEquiv_mul (f g : M ≃ₗ[R] M) :
65+
ofLinearEquiv (f * g) = ofLinearEquiv f * ofLinearEquiv g := by
66+
rfl
67+
68+
theorem ofLinearEquiv_inv (f : M ≃ₗ[R] M) :
69+
ofLinearEquiv (f⁻¹) = (ofLinearEquiv f)⁻¹ := by
70+
rfl
71+
5672
variable (R M) in
5773
/-- The general linear group on `R` and `M` is multiplicatively equivalent to the type of linear
5874
equivalences between `M` and itself. -/

Mathlib/LinearAlgebra/Matrix/Dual.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ open Matrix Module
2121

2222
section Transpose
2323

24-
variable {K V₁ V₂ ι₁ ι₂ : Type*} [Field K] [AddCommGroup V₁] [Module K V₁] [AddCommGroup V₂]
24+
variable {K V₁ V₂ ι₁ ι₂ : Type*} [CommSemiring K] [AddCommGroup V₁] [Module K V₁] [AddCommGroup V₂]
2525
[Module K V₂] [Fintype ι₁] [Fintype ι₂] [DecidableEq ι₁] [DecidableEq ι₂] {B₁ : Basis ι₁ K V₁}
2626
{B₂ : Basis ι₂ K V₂}
2727

Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ lemma det_ne_zero [Nontrivial R] (g : GL n R) : g.val.det ≠ 0 :=
7474
def toLin : GL n R ≃* LinearMap.GeneralLinearGroup R (n → R) :=
7575
Units.mapEquiv toLinAlgEquiv'.toMulEquiv
7676

77+
/-- The isomorphism from `GL n R` to the general linear group of a module
78+
associated with a basis. -/
79+
noncomputable def toLin'
80+
{V : Type*} [AddCommGroup V] [Module R V] (b : Module.Basis n R V) :
81+
GL n R ≃* LinearMap.GeneralLinearGroup R V :=
82+
toLin.trans <| LinearMap.GeneralLinearGroup.congrLinearEquiv b.equivFun.symm
83+
84+
lemma toLin'_apply {V : Type*} [AddCommGroup V] [Module R V]
85+
(b : Module.Basis n R V) (M : GL n R) (v : V) :
86+
(toLin' b M).toLinearEquiv v = Fintype.linearCombination R ⇑b (↑M *ᵥ (b.repr v)) := by
87+
simp [toLin', toLin, Fintype.linearCombination_apply, MulEquiv.trans_apply]
88+
7789
/-- Given a matrix with invertible determinant, we get an element of `GL n R`. -/
7890
@[simps! val]
7991
def mk' (A : Matrix n n R) (_ : Invertible (Matrix.det A)) : GL n R :=

0 commit comments

Comments
 (0)