Skip to content

Commit 4d8e83e

Browse files
committed
chore(LinearAlgebra/Matrix): import less analysis (#31480)
Move the definition of eigenvalues of hermitian matrices to `Analysis.Matrix`, and the corresponding lemmas about positive (semi)definite matrices too. Some lemmas could be generalised instead of moved, and I have done so. Ultimately, it would be great for `LinearAlgebra.Matrix` to import no analysis at all. But this is a longer term goal.
1 parent e619dd1 commit 4d8e83e

File tree

9 files changed

+122
-75
lines changed

9 files changed

+122
-75
lines changed

β€ŽMathlib.leanβ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1805,6 +1805,8 @@ import Mathlib.Analysis.LocallyConvex.WithSeminorms
18051805
import Mathlib.Analysis.Matrix
18061806
import Mathlib.Analysis.Matrix.Normed
18071807
import Mathlib.Analysis.Matrix.Order
1808+
import Mathlib.Analysis.Matrix.PosDef
1809+
import Mathlib.Analysis.Matrix.Spectrum
18081810
import Mathlib.Analysis.MeanInequalities
18091811
import Mathlib.Analysis.MeanInequalitiesPow
18101812
import Mathlib.Analysis.MellinInversion
@@ -4457,7 +4459,6 @@ import Mathlib.LinearAlgebra.Matrix.SchurComplement
44574459
import Mathlib.LinearAlgebra.Matrix.SemiringInverse
44584460
import Mathlib.LinearAlgebra.Matrix.SesquilinearForm
44594461
import Mathlib.LinearAlgebra.Matrix.SpecialLinearGroup
4460-
import Mathlib.LinearAlgebra.Matrix.Spectrum
44614462
import Mathlib.LinearAlgebra.Matrix.StdBasis
44624463
import Mathlib.LinearAlgebra.Matrix.Swap
44634464
import Mathlib.LinearAlgebra.Matrix.Symmetric

β€ŽMathlib/Algebra/Star/Basic.leanβ€Ž

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ variable (R) in
172172
theorem star_one [MulOneClass R] [StarMul R] : star (1 : R) = 1 :=
173173
op_injective <| (starMulEquiv : R ≃* Rᡐᡒᡖ).map_one.trans op_one.symm
174174

175+
@[simp]
176+
lemma Pi.star_mulSingle {ΞΉ : Type*} {R : ΞΉ β†’ Type*} [DecidableEq ΞΉ] [βˆ€ i, MulOneClass (R i)]
177+
[βˆ€ i, StarMul (R i)] (i : ΞΉ) (r : R i) : star (mulSingle i r) = mulSingle i (star r) := by
178+
ext; exact apply_mulSingle (fun _ ↦ star) (fun _ ↦ star_one _) ..
179+
175180
@[simp]
176181
theorem star_pow [Monoid R] [StarMul R] (x : R) (n : β„•) : star (x ^ n) = star x ^ n :=
177182
op_injective <|
@@ -232,6 +237,11 @@ variable (R) in
232237
theorem star_zero [AddMonoid R] [StarAddMonoid R] : star (0 : R) = 0 :=
233238
(starAddEquiv : R ≃+ R).map_zero
234239

240+
@[simp]
241+
lemma Pi.star_single {ΞΉ : Type*} {R : ΞΉ β†’ Type*} [DecidableEq ΞΉ] [βˆ€ i, AddMonoid (R i)]
242+
[βˆ€ i, StarAddMonoid (R i)] (i : ΞΉ) (r : R i) : star (single i r) = single i (star r) := by
243+
ext; exact apply_single (fun _ ↦ star) (fun _ ↦ star_zero _) ..
244+
235245
@[simp]
236246
theorem star_eq_zero [AddMonoid R] [StarAddMonoid R] {x : R} : star x = 0 ↔ x = 0 :=
237247
starAddEquiv.map_eq_zero_iff (M := R)

β€ŽMathlib/Analysis/InnerProductSpace/Positive.leanβ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ Copyright (c) 2022 Anatole Dedecker. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Anatole Dedecker
55
-/
6-
import Mathlib.Analysis.InnerProductSpace.Adjoint
76
import Mathlib.Analysis.InnerProductSpace.Spectrum
87
import Mathlib.LinearAlgebra.Matrix.PosDef
98

β€ŽMathlib/Analysis/Matrix/Order.leanβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Monica Omar
55
-/
66
import Mathlib.Analysis.CStarAlgebra.ContinuousFunctionalCalculus.Instances
7+
import Mathlib.Analysis.Matrix.PosDef
78
import Mathlib.Analysis.SpecialFunctions.ContinuousFunctionalCalculus.Rpow.Basic
89
import Mathlib.LinearAlgebra.Matrix.HermitianFunctionalCalculus
9-
import Mathlib.LinearAlgebra.Matrix.PosDef
1010

1111
/-!
1212
# The partial order on matrices
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/-
2+
Copyright (c) 2022 Alexander Bentkamp. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Alexander Bentkamp, Mohanad Ahmed
5+
-/
6+
import Mathlib.Analysis.Matrix.Spectrum
7+
import Mathlib.LinearAlgebra.Matrix.PosDef
8+
9+
/-!
10+
# Spectrum of positive definite matrices
11+
12+
This file proves that eigenvalues of positive (semi)definite matrices are (nonnegative) positive.
13+
-/
14+
15+
open WithLp
16+
open scoped ComplexOrder
17+
18+
namespace Matrix
19+
variable {m n π•œ : Type*} [Fintype m] [Fintype n] [RCLike π•œ]
20+
21+
/-! ### Positive semidefinite matrices -/
22+
23+
namespace PosSemidef
24+
25+
/-- The eigenvalues of a positive semi-definite matrix are non-negative -/
26+
lemma eigenvalues_nonneg [DecidableEq n] {A : Matrix n n π•œ}
27+
(hA : Matrix.PosSemidef A) (i : n) : 0 ≀ hA.1.eigenvalues i :=
28+
(hA.re_dotProduct_nonneg _).trans_eq (hA.1.eigenvalues_eq _).symm
29+
30+
lemma det_nonneg [DecidableEq n] {M : Matrix n n π•œ} (hM : M.PosSemidef) :
31+
0 ≀ M.det := by
32+
rw [hM.isHermitian.det_eq_prod_eigenvalues]
33+
exact Finset.prod_nonneg fun i _ ↦ by simpa using hM.eigenvalues_nonneg i
34+
35+
end PosSemidef
36+
37+
lemma eigenvalues_conjTranspose_mul_self_nonneg (A : Matrix m n π•œ) [DecidableEq n] (i : n) :
38+
0 ≀ (isHermitian_conjTranspose_mul_self A).eigenvalues i :=
39+
(posSemidef_conjTranspose_mul_self _).eigenvalues_nonneg _
40+
41+
lemma eigenvalues_self_mul_conjTranspose_nonneg (A : Matrix m n π•œ) [DecidableEq m] (i : m) :
42+
0 ≀ (isHermitian_mul_conjTranspose_self A).eigenvalues i :=
43+
(posSemidef_self_mul_conjTranspose _).eigenvalues_nonneg _
44+
45+
/-- A Hermitian matrix is positive semi-definite if and only if its eigenvalues are non-negative. -/
46+
lemma IsHermitian.posSemidef_iff_eigenvalues_nonneg [DecidableEq n] {A : Matrix n n π•œ}
47+
(hA : IsHermitian A) : PosSemidef A ↔ 0 ≀ hA.eigenvalues := by
48+
refine ⟨fun h => h.eigenvalues_nonneg, fun h => ?_⟩
49+
rw [hA.spectral_theorem]
50+
refine (posSemidef_diagonal_iff.mpr ?_).mul_mul_conjTranspose_same _
51+
simpa using h
52+
53+
@[deprecated (since := "2025-08-17")] alias ⟨_, IsHermitian.posSemidef_of_eigenvalues_nonneg⟩ :=
54+
IsHermitian.posSemidef_iff_eigenvalues_nonneg
55+
56+
lemma PosSemidef.trace_eq_zero_iff {A : Matrix n n π•œ} (hA : A.PosSemidef) :
57+
A.trace = 0 ↔ A = 0 := by
58+
refine ⟨fun h => ?_, fun h => h β–Έ trace_zero n π•œβŸ©
59+
classical
60+
simp_rw [hA.isHermitian.trace_eq_sum_eigenvalues, ← RCLike.ofReal_sum,
61+
RCLike.ofReal_eq_zero, Finset.sum_eq_zero_iff_of_nonneg (s := Finset.univ)
62+
(by simpa using hA.eigenvalues_nonneg), Finset.mem_univ, true_imp_iff] at h
63+
exact funext_iff.eq β–Έ hA.isHermitian.eigenvalues_eq_zero_iff.mp <| h
64+
65+
/-! ### Positive definite matrices -/
66+
67+
namespace PosDef
68+
69+
/-- The eigenvalues of a positive definite matrix are positive. -/
70+
lemma eigenvalues_pos [DecidableEq n] {A : Matrix n n π•œ}
71+
(hA : Matrix.PosDef A) (i : n) : 0 < hA.1.eigenvalues i := by
72+
simp only [hA.1.eigenvalues_eq]
73+
exact hA.re_dotProduct_pos <| (ofLp_eq_zero 2).ne.2 <|
74+
hA.1.eigenvectorBasis.orthonormal.ne_zero i
75+
76+
/-- A Hermitian matrix is positive-definite if and only if its eigenvalues are positive. -/
77+
lemma _root_.Matrix.IsHermitian.posDef_iff_eigenvalues_pos [DecidableEq n] {A : Matrix n n π•œ}
78+
(hA : A.IsHermitian) : A.PosDef ↔ βˆ€ i, 0 < hA.eigenvalues i := by
79+
refine ⟨fun h => h.eigenvalues_pos, fun h => ?_⟩
80+
rw [hA.spectral_theorem]
81+
refine (posDef_diagonal_iff.mpr <| by simpa using h).mul_mul_conjTranspose_same ?_
82+
rw [vecMul_injective_iff_isUnit, ← Unitary.val_toUnits_apply]
83+
exact Units.isUnit _
84+
85+
lemma det_pos [DecidableEq n] {M : Matrix n n π•œ} (hM : M.PosDef) : 0 < det M := by
86+
rw [hM.isHermitian.det_eq_prod_eigenvalues]
87+
apply Finset.prod_pos
88+
intro i _
89+
simpa using hM.eigenvalues_pos i
90+
91+
end PosDef
92+
end Matrix

β€ŽMathlib/Combinatorics/SimpleGraph/LapMatrix.leanβ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ Authors: Adrian WΓΌthrich
55
-/
66
import Mathlib.Analysis.Matrix.Order
77
import Mathlib.Combinatorics.SimpleGraph.AdjMatrix
8-
import Mathlib.LinearAlgebra.Matrix.PosDef
98

109
/-!
1110
# Laplacian Matrix

β€ŽMathlib/LinearAlgebra/Matrix/HermitianFunctionalCalculus.leanβ€Ž

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ Copyright (c) 2024 Jon Bannon. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Jon Bannon, Jireh Loreaux
55
-/
6-
7-
import Mathlib.LinearAlgebra.Matrix.Spectrum
8-
import Mathlib.LinearAlgebra.Eigenspace.Matrix
96
import Mathlib.Analysis.CStarAlgebra.ContinuousFunctionalCalculus.Unique
7+
import Mathlib.Analysis.Matrix.Spectrum
108
import Mathlib.Topology.ContinuousMap.Units
119

1210
/-!

β€ŽMathlib/LinearAlgebra/Matrix/PosDef.leanβ€Ž

Lines changed: 16 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Alexander Bentkamp, Mohanad Ahmed
55
-/
66
import Mathlib.Algebra.Order.Ring.Star
7-
import Mathlib.LinearAlgebra.Matrix.Spectrum
7+
import Mathlib.LinearAlgebra.Matrix.DotProduct
8+
import Mathlib.LinearAlgebra.Matrix.Hermitian
89
import Mathlib.LinearAlgebra.Matrix.Vec
910
import Mathlib.LinearAlgebra.QuadraticForm.Basic
1011

@@ -32,6 +33,10 @@ order on matrices on `ℝ` or `β„‚`.
3233
* `Matrix.PosDef.isUnit`: A positive definite matrix in a field is invertible.
3334
-/
3435

36+
-- TODO:
37+
-- assert_not_exists MonoidAlgebra
38+
assert_not_exists Matrix.IsHermitian.eigenvalues
39+
3540
open WithLp
3641

3742
open scoped ComplexOrder
@@ -178,20 +183,11 @@ protected theorem smul {Ξ± : Type*} [CommSemiring Ξ±] [PartialOrder Ξ±] [StarRin
178183
simp only [smul_mulVec, dotProduct_smul]
179184
exact smul_nonneg ha (hx.2 _)
180185

181-
/-- The eigenvalues of a positive semi-definite matrix are non-negative -/
182-
lemma eigenvalues_nonneg [DecidableEq n] {A : Matrix n n π•œ}
183-
(hA : Matrix.PosSemidef A) (i : n) : 0 ≀ hA.1.eigenvalues i :=
184-
(hA.re_dotProduct_nonneg _).trans_eq (hA.1.eigenvalues_eq _).symm
185-
186-
theorem trace_nonneg {A : Matrix n n π•œ} (hA : A.PosSemidef) : 0 ≀ A.trace := by
187-
classical
188-
simp [hA.isHermitian.trace_eq_sum_eigenvalues, ← map_sum,
189-
Finset.sum_nonneg (fun _ _ => hA.eigenvalues_nonneg _)]
186+
lemma diag_nonneg {A : Matrix n n R} (hA : A.PosSemidef) {i : n} : 0 ≀ A i i := by
187+
classical simpa [trace] using hA.2 <| Pi.single i 1
190188

191-
theorem det_nonneg [DecidableEq n] {M : Matrix n n π•œ} (hM : M.PosSemidef) :
192-
0 ≀ M.det := by
193-
rw [hM.isHermitian.det_eq_prod_eigenvalues]
194-
exact Finset.prod_nonneg fun i _ ↦ by simpa using hM.eigenvalues_nonneg i
189+
lemma trace_nonneg [AddLeftMono R] {A : Matrix n n R} (hA : A.PosSemidef) : 0 ≀ A.trace :=
190+
Fintype.sum_nonneg fun _ ↦ hA.diag_nonneg
195191

196192
end PosSemidef
197193

@@ -234,34 +230,6 @@ theorem trace_mul_conjTranspose_self_eq_zero_iff {A : Matrix m n R} :
234230

235231
end trace
236232

237-
lemma eigenvalues_conjTranspose_mul_self_nonneg (A : Matrix m n π•œ) [DecidableEq n] (i : n) :
238-
0 ≀ (isHermitian_conjTranspose_mul_self A).eigenvalues i :=
239-
(posSemidef_conjTranspose_mul_self _).eigenvalues_nonneg _
240-
241-
lemma eigenvalues_self_mul_conjTranspose_nonneg (A : Matrix m n π•œ) [DecidableEq m] (i : m) :
242-
0 ≀ (isHermitian_mul_conjTranspose_self A).eigenvalues i :=
243-
(posSemidef_self_mul_conjTranspose _).eigenvalues_nonneg _
244-
245-
/-- A Hermitian matrix is positive semi-definite if and only if its eigenvalues are non-negative. -/
246-
lemma IsHermitian.posSemidef_iff_eigenvalues_nonneg [DecidableEq n] {A : Matrix n n π•œ}
247-
(hA : IsHermitian A) : PosSemidef A ↔ 0 ≀ hA.eigenvalues := by
248-
refine ⟨fun h => h.eigenvalues_nonneg, fun h => ?_⟩
249-
rw [hA.spectral_theorem]
250-
refine (posSemidef_diagonal_iff.mpr ?_).mul_mul_conjTranspose_same _
251-
simpa using h
252-
253-
@[deprecated (since := "2025-08-17")] alias ⟨_, IsHermitian.posSemidef_of_eigenvalues_nonneg⟩ :=
254-
IsHermitian.posSemidef_iff_eigenvalues_nonneg
255-
256-
theorem PosSemidef.trace_eq_zero_iff {A : Matrix n n π•œ} (hA : A.PosSemidef) :
257-
A.trace = 0 ↔ A = 0 := by
258-
refine ⟨fun h => ?_, fun h => h β–Έ trace_zero n π•œβŸ©
259-
classical
260-
simp_rw [hA.isHermitian.trace_eq_sum_eigenvalues, ← RCLike.ofReal_sum,
261-
RCLike.ofReal_eq_zero, Finset.sum_eq_zero_iff_of_nonneg (s := Finset.univ)
262-
(by simpa using hA.eigenvalues_nonneg), Finset.mem_univ, true_imp_iff] at h
263-
exact funext_iff.eq β–Έ hA.isHermitian.eigenvalues_eq_zero_iff.mp <| h
264-
265233
section conjugate
266234
variable [DecidableEq n] {U x : Matrix n n R}
267235

@@ -470,32 +438,12 @@ theorem toQuadraticForm' [DecidableEq n] {M : Matrix n n ℝ} (hM : M.PosDef) :
470438
toLinearMapβ‚‚'_apply']
471439
apply hM.2 x hx
472440

473-
/-- The eigenvalues of a positive definite matrix are positive. -/
474-
lemma eigenvalues_pos [DecidableEq n] {A : Matrix n n π•œ}
475-
(hA : Matrix.PosDef A) (i : n) : 0 < hA.1.eigenvalues i := by
476-
simp only [hA.1.eigenvalues_eq]
477-
exact hA.re_dotProduct_pos <| (ofLp_eq_zero 2).ne.2 <|
478-
hA.1.eigenvectorBasis.orthonormal.ne_zero i
479-
480-
/-- A Hermitian matrix is positive-definite if and only if its eigenvalues are positive. -/
481-
lemma _root_.Matrix.IsHermitian.posDef_iff_eigenvalues_pos [DecidableEq n] {A : Matrix n n π•œ}
482-
(hA : A.IsHermitian) : A.PosDef ↔ βˆ€ i, 0 < hA.eigenvalues i := by
483-
refine ⟨fun h => h.eigenvalues_pos, fun h => ?_⟩
484-
rw [hA.spectral_theorem]
485-
refine (posDef_diagonal_iff.mpr <| by simpa using h).mul_mul_conjTranspose_same ?_
486-
rw [vecMul_injective_iff_isUnit, ← Unitary.val_toUnits_apply]
487-
exact Units.isUnit _
488-
489-
theorem trace_pos [Nonempty n] {A : Matrix n n π•œ} (hA : A.PosDef) : 0 < A.trace := by
490-
classical
491-
simp [hA.isHermitian.trace_eq_sum_eigenvalues, ← map_sum,
492-
Finset.sum_pos (fun _ _ => hA.eigenvalues_pos _)]
493-
494-
theorem det_pos [DecidableEq n] {M : Matrix n n π•œ} (hM : M.PosDef) : 0 < det M := by
495-
rw [hM.isHermitian.det_eq_prod_eigenvalues]
496-
apply Finset.prod_pos
497-
intro i _
498-
simpa using hM.eigenvalues_pos i
441+
lemma diag_pos [Nontrivial R] {A : Matrix n n R} (hA : A.PosDef) {i : n} : 0 < A i i := by
442+
classical simpa [trace] using hA.2 <| Pi.single i 1
443+
444+
lemma trace_pos [Nontrivial R] [IsOrderedCancelAddMonoid R] [Nonempty n] {A : Matrix n n R}
445+
(hA : A.PosDef) : 0 < A.trace :=
446+
Finset.sum_pos (fun _ _ ↦ hA.diag_pos) Finset.univ_nonempty
499447

500448
section Field
501449
variable {K : Type*} [Field K] [PartialOrder K] [StarRing K]

0 commit comments

Comments
Β (0)