@@ -26,7 +26,7 @@ namespace Matrix
2626
2727section Finite
2828
29- variable {m n R A : Type *} [CommRing R] [Finite m] [Finite n] (M : Matrix m n R)
29+ variable {m n R A : Type *} [NonUnitalNonAssocSemiring R] [Finite m] [Finite n] (M : Matrix m n R)
3030
3131attribute [local instance ] Fintype.ofFinite
3232
@@ -39,29 +39,87 @@ def SeparatingLeft : Prop :=
3939 (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0 ) → v = 0 )
4040
4141/-- A matrix `M` is nondegenerate if it is both left-separating and right-separating. -/
42+ @[mk_iff]
4243structure Nondegenerate (M : Matrix m n R) : Prop where
4344 separatingLeft : SeparatingLeft M
4445 separatingRight : SeparatingRight M
4546
4647end Finite
4748
48- variable {m n R A : Type *} [CommRing R] [Fintype m] [Fintype n] [CommRing A] [IsDomain A]
49- {M : Matrix m n R}
49+ variable {m n R : Type *} [CommRing R] {M : Matrix m n R}
5050
51- lemma separatingRight_def : M.SeparatingRight ↔ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0 ) → w = 0 ) := by
51+ lemma separatingRight_def [Fintype m] [Fintype n] :
52+ M.SeparatingRight ↔ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0 ) → w = 0 ) := by
5253 refine forall_congr' fun w ↦ ⟨fun hM hw ↦ hM ?_, fun hM hw ↦ hM ?_⟩ <;>
5354 convert! hw
5455
55- lemma separatingLeft_def : M.SeparatingLeft ↔ (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0 ) → v = 0 ) := by
56+ lemma separatingLeft_def [Fintype m] [Fintype n] :
57+ M.SeparatingLeft ↔ (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0 ) → v = 0 ) := by
5658 refine forall_congr' fun v ↦ ⟨fun hM hv ↦ hM ?_, fun hM hv ↦ hM ?_⟩ <;>
5759 convert! hv
5860
59- lemma nondegenerate_def : M.Nondegenerate ↔
60- (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0 ) → v = 0 ) ∧ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0 ) → w = 0 ) := by
61+ lemma nondegenerate_def [Fintype m] [Fintype n] :
62+ M.Nondegenerate ↔
63+ (∀ v, (∀ w, v ⬝ᵥ M *ᵥ w = 0 ) → v = 0 ) ∧ (∀ w, (∀ v, v ⬝ᵥ M *ᵥ w = 0 ) → w = 0 ) := by
6164 constructor
6265 · exact fun h ↦ ⟨separatingLeft_def.mp h.1 , separatingRight_def.mp h.2 ⟩
6366 · exact fun h ↦ ⟨separatingLeft_def.mpr h.1 , separatingRight_def.mpr h.2 ⟩
6467
68+ theorem separatingLeft_iff_forall_vecMul_eq_zero [Fintype m] [Finite n] :
69+ M.SeparatingLeft ↔ ∀ v, v ᵥ* M = 0 → v = 0 := by
70+ have := Fintype.ofFinite n
71+ rw [separatingLeft_def]
72+ refine ⟨fun h v hv ↦ h v fun w ↦ ?_, fun h w hw ↦ h w <| funext fun i ↦ ?_⟩
73+ · simp [dotProduct_mulVec, hv]
74+ · classical simpa using ! hw <| Pi.single i 1
75+
76+ theorem separatingRight_iff_forall_mulVec_eq_zero [Finite m] [Fintype n] :
77+ M.SeparatingRight ↔ ∀ v, M *ᵥ v = 0 → v = 0 := by
78+ have := Fintype.ofFinite m
79+ rw [separatingRight_def]
80+ refine ⟨fun h v hv ↦ h v fun w ↦ ?_, fun h w hw ↦ h w <| funext fun i ↦ ?_⟩
81+ · simp [hv]
82+ · classical simpa using hw <| Pi.single i 1
83+
84+ theorem SeparatingLeft.eq_zero_of_vecMul_eq_zero [Fintype m] [Finite n] (hM : M.SeparatingLeft)
85+ {v : m → R} (hv : v ᵥ* M = 0 ) : v = 0 :=
86+ separatingLeft_iff_forall_vecMul_eq_zero.mp hM v hv
87+
88+ theorem SeparatingRight.eq_zero_of_mulVec_eq_zero [Finite m] [Fintype n] (hM : M.SeparatingRight)
89+ {v : n → R} (hv : M *ᵥ v = 0 ) : v = 0 :=
90+ separatingRight_iff_forall_mulVec_eq_zero.mp hM v hv
91+
92+ theorem nondegenerate_iff_forall_vecMul_and_mulVec_eq_zero [Fintype m] [Fintype n] :
93+ M.Nondegenerate ↔ (∀ v, v ᵥ* M = 0 → v = 0 ) ∧ (∀ v, M *ᵥ v = 0 → v = 0 ) := by
94+ rw [nondegenerate_iff, separatingLeft_iff_forall_vecMul_eq_zero,
95+ separatingRight_iff_forall_mulVec_eq_zero]
96+
97+ @[simp]
98+ theorem separatingLeft_transpose_iff [Finite m] [Finite n] :
99+ Mᵀ.SeparatingLeft ↔ M.SeparatingRight := by
100+ have := Fintype.ofFinite m
101+ have := Fintype.ofFinite n
102+ simp_rw [separatingLeft_def, separatingRight_def, dotProduct_transpose_mulVec]
103+
104+ alias ⟨_, SeparatingRight.separatingLeft_transpose⟩ := separatingLeft_transpose_iff
105+
106+ @[simp]
107+ theorem separatingRight_transpose_iff [Finite m] [Finite n] :
108+ Mᵀ.SeparatingRight ↔ M.SeparatingLeft := by
109+ have := Fintype.ofFinite m
110+ have := Fintype.ofFinite n
111+ simp_rw [separatingRight_def, separatingLeft_def, dotProduct_transpose_mulVec]
112+
113+ alias ⟨_, SeparatingLeft.separatingRight_transpose⟩ := separatingRight_transpose_iff
114+
115+ @[simp]
116+ theorem nondegenerate_transpose_iff [Finite m] [Finite n] : Mᵀ.Nondegenerate ↔ M.Nondegenerate := by
117+ simp [nondegenerate_iff, and_comm]
118+
119+ alias ⟨_, Nondegenerate.transpose⟩ := nondegenerate_transpose_iff
120+
121+ variable [Fintype m] [Fintype n]
122+
65123/-- If `M` is nondegenerate and `w * M * v = 0` for all `w`, then `v = 0`. -/
66124theorem Nondegenerate.eq_zero_of_ortho (hM : Nondegenerate M) {v : m → R}
67125 (hv : ∀ w, v ⬝ᵥ M *ᵥ w = 0 ) : v = 0 :=
@@ -73,42 +131,51 @@ theorem Nondegenerate.exists_not_ortho_of_ne_zero (hM : Nondegenerate M)
73131 not_forall.mp (mt hM.eq_zero_of_ortho hv)
74132
75133/-- If `M` is nondegenerate and `w * M * v = 0` for all `v`, then `w = 0`. -/
76- theorem Nondegenerate.eq_zero_of_ortho' {M : Matrix m n R} (hM : Nondegenerate M) {w : n → R}
134+ theorem Nondegenerate.eq_zero_of_ortho' (hM : Nondegenerate M) {w : n → R}
77135 (hw : ∀ v, v ⬝ᵥ M *ᵥ w = 0 ) : w = 0 :=
78136 (nondegenerate_def.mp hM).2 w hw
79137
80138/-- If `M` is nondegenerate and `w ≠ 0`, then there is some `v` such that `v * M * w ≠ 0`. -/
81- theorem Nondegenerate.exists_not_ortho_of_ne_zero' {M : Matrix m n R} (hM : Nondegenerate M)
82- {w : n → R} (hw : w ≠ 0 ) : ∃ v, v ⬝ᵥ M *ᵥ w ≠ 0 :=
139+ theorem Nondegenerate.exists_not_ortho_of_ne_zero' (hM : Nondegenerate M) {w : n → R} (hw : w ≠ 0 ) :
140+ ∃ v, v ⬝ᵥ M *ᵥ w ≠ 0 :=
83141 not_forall.mp (mt hM.eq_zero_of_ortho' hw)
84142
85143section Determinant
86- variable [DecidableEq m] {M : Matrix m m A}
144+ variable [DecidableEq m] {M : Matrix m m R}
145+
146+ open scoped nonZeroDivisors
147+
148+ private theorem SeparatingLeft.of_det_mem_nonZeroDivisors (hM : M.det ∈ R⁰) : M.SeparatingLeft := by
149+ refine separatingLeft_def.mpr fun v h ↦ funext fun i ↦ mem_nonZeroDivisors_iff_left.mp hM _ ?_
150+ simpa using h <| M.cramer <| Pi.single i 1
151+
152+ theorem Nondegenerate.of_det_mem_nonZeroDivisors (hM : M.det ∈ R⁰) : M.Nondegenerate where
153+ separatingLeft := .of_det_mem_nonZeroDivisors hM
154+ separatingRight := separatingLeft_transpose_iff.mp <| .of_det_mem_nonZeroDivisors <| by simpa
87155
88- /-- If `M` is square and has nonzero determinant, then `M` as a bilinear form on `n → A ` is
156+ /-- If `M` is square and has nonzero determinant, then `M` as a bilinear form on `n → R ` is
89157nondegenerate. The "iff" implication, `nondegenerate_iff_det_ne_zero`, is proved in a later file.
90158
91159See also `BilinForm.nondegenerateOfDetNeZero'` and `BilinForm.nondegenerateOfDetNeZero`.
92160-/
93- theorem nondegenerate_of_det_ne_zero (hM : M.det ≠ 0 ) : Nondegenerate M := by
94- refine nondegenerate_def.mpr ⟨fun v h ↦ ?_, fun w h ↦ ?_⟩
95- · ext i
96- specialize h (M.cramer (Pi.single i 1 ))
97- simp_all
98- · ext i
99- contrapose! h
100- use Pi.single i 1 ᵥ* M.adjugate
101- rw [dotProduct_mulVec, vecMul_vecMul, adjugate_mul]
102- simp_all [dotProduct, smul_apply, smul_eq_mul, Matrix.one_apply]
103-
104- theorem eq_zero_of_vecMul_eq_zero (hM : M.det ≠ 0 ) {v : m → A}
161+ theorem nondegenerate_of_det_ne_zero [NoZeroDivisors R] (hM : M.det ≠ 0 ) : M.Nondegenerate :=
162+ .of_det_mem_nonZeroDivisors <| mem_nonZeroDivisors_of_ne_zero hM
163+
164+ theorem eq_zero_of_det_mem_nonZeroDivisors_of_vecMul_eq_zero (hM : M.det ∈ R⁰)
165+ {v : m → R} (hv : v ᵥ* M = 0 ) : v = 0 :=
166+ Nondegenerate.of_det_mem_nonZeroDivisors hM |>.separatingLeft.eq_zero_of_vecMul_eq_zero hv
167+
168+ theorem eq_zero_of_vecMul_eq_zero [NoZeroDivisors R] (hM : M.det ≠ 0 ) {v : m → R}
105169 (hv : v ᵥ* M = 0 ) : v = 0 :=
106- (nondegenerate_of_det_ne_zero hM).eq_zero_of_ortho fun w => by
107- rw [dotProduct_mulVec, hv, zero_dotProduct]
170+ nondegenerate_of_det_ne_zero hM |>.separatingLeft.eq_zero_of_vecMul_eq_zero hv
171+
172+ theorem eq_zero_of_det_mem_nonZeroDivisors_of_mulVec_eq_zero (hM : M.det ∈ R⁰)
173+ {v : m → R} (hv : M *ᵥ v = 0 ) : v = 0 :=
174+ Nondegenerate.of_det_mem_nonZeroDivisors hM |>.separatingRight.eq_zero_of_mulVec_eq_zero hv
108175
109- theorem eq_zero_of_mulVec_eq_zero (hM : M.det ≠ 0 ) {v : m → A }
176+ theorem eq_zero_of_mulVec_eq_zero [NoZeroDivisors R] (hM : M.det ≠ 0 ) {v : m → R }
110177 (hv : M *ᵥ v = 0 ) : v = 0 :=
111- eq_zero_of_vecMul_eq_zero ( by rwa [det_transpose]) ((vecMul_transpose M v).trans hv)
178+ nondegenerate_of_det_ne_zero hM |>.separatingRight.eq_zero_of_mulVec_eq_zero hv
112179
113180end Determinant
114181
0 commit comments