Skip to content

Commit 41e1a24

Browse files
feat(LinearAlgebra/Matrix/PosDef): kronecker of positive (semi-)definite matrices is positive (semi-)definite (#28097)
This first shows that `U * x * star U` is positive (semi-)definite if and only if `x` is, for an invertible matrix `U` in a not necessarily commutative star-ring. Then using the spectral theorem, it follows that the kronecker of positive (semi-)definite matrices is positive (semi-)definite. Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
1 parent 2c2d756 commit 41e1a24

File tree

7 files changed

+138
-5
lines changed

7 files changed

+138
-5
lines changed

Mathlib/Algebra/Algebra/StrictPositivity.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,21 @@ lemma _root_.isStrictlyPositive_one [LE A] [Monoid A] [Zero A] [ZeroLEOneClass A
6666

6767
end basic
6868

69+
section StarOrderedRing
70+
variable [Semiring A] [StarRing A] [PartialOrder A] [StarOrderedRing A]
71+
72+
lemma _root_.IsUnit.isStrictlyPositive_conjugate_iff {u a : A} (hu : IsUnit u) :
73+
IsStrictlyPositive (u * a * star u) ↔ IsStrictlyPositive a := by
74+
simp_rw [IsStrictlyPositive.iff_of_unital, hu.conjugate_nonneg_iff]
75+
lift u to Aˣ using hu
76+
rw [← Units.coe_star, Units.isUnit_mul_units, Units.isUnit_units_mul]
77+
78+
lemma _root_.IsUnit.isStrictlyPositive_conjugate_iff' {u a : A} (hu : IsUnit u) :
79+
IsStrictlyPositive (star u * a * u) ↔ IsStrictlyPositive a := by
80+
simpa using hu.star.isStrictlyPositive_conjugate_iff
81+
82+
end StarOrderedRing
83+
6984
section Algebra
7085

7186
variable {𝕜 : Type*} [Ring A] [PartialOrder A]

Mathlib/Algebra/Order/Star/Basic.lean

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,17 @@ lemma star_lt_one_iff {x : R} : star x < 1 ↔ x < 1 := by
336336
protected theorem IsSelfAdjoint.sq_nonneg {a : R} (ha : IsSelfAdjoint a) : 0 ≤ a ^ 2 := by
337337
simp [sq, ha.mul_self_nonneg]
338338

339+
lemma IsUnit.conjugate_nonneg_iff {u x : R} (hu : IsUnit u) :
340+
0 ≤ u * x * star u ↔ 0 ≤ x := by
341+
refine ⟨fun h ↦ ?_, fun h ↦ conjugate_nonneg' h _⟩
342+
obtain ⟨v, hv⟩ := hu.exists_left_inv
343+
have := by simpa [← mul_assoc] using conjugate_nonneg' h v
344+
rwa [hv, one_mul, mul_assoc, ← star_mul, hv, star_one, mul_one] at this
345+
346+
lemma IsUnit.conjugate_nonneg_iff' {u x : R} (hu : IsUnit u) :
347+
0 ≤ star u * x * u ↔ 0 ≤ x := by
348+
simpa using hu.star.conjugate_nonneg_iff
349+
339350
end Semiring
340351

341352
namespace MulOpposite

Mathlib/Algebra/Star/SelfAdjoint.lean

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,19 @@ theorem pow {x : R} (hx : IsSelfAdjoint x) (n : ℕ) : IsSelfAdjoint (x ^ n) :=
183183
simp only [isSelfAdjoint_iff, star_pow, hx.star_eq]
184184

185185
@[grind =]
186-
lemma _root_.isSelfAdjoint_conjugate_iff_of_isUnit {a u : R} (hu : IsUnit u) :
186+
lemma _root_.IsUnit.isSelfAdjoint_conjugate_iff {a u : R} (hu : IsUnit u) :
187187
IsSelfAdjoint (u * a * star u) ↔ IsSelfAdjoint a := by
188188
simp [IsSelfAdjoint, mul_assoc, hu.mul_right_inj, hu.star.mul_left_inj]
189189

190190
@[grind =]
191-
lemma _root_.isSelfAdjoint_conjugate_iff_of_isUnit' {a u : R} (hu : IsUnit u) :
191+
lemma _root_.IsUnit.isSelfAdjoint_conjugate_iff' {a u : R} (hu : IsUnit u) :
192192
IsSelfAdjoint (star u * a * u) ↔ IsSelfAdjoint a := by
193-
simpa using isSelfAdjoint_conjugate_iff_of_isUnit hu.star
193+
simpa using hu.star.isSelfAdjoint_conjugate_iff
194+
195+
@[deprecated (since := "2025-09-28")] alias _root_.isSelfAdjoint_conjugate_iff_of_isUnit :=
196+
IsUnit.isSelfAdjoint_conjugate_iff
197+
@[deprecated (since := "2025-09-28")] alias _root_.isSelfAdjoint_conjugate_iff_of_isUnit' :=
198+
IsUnit.isSelfAdjoint_conjugate_iff'
194199

195200
end Monoid
196201

Mathlib/Analysis/Matrix/Order.lean

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,30 @@ theorem PosDef.commute_iff {A B : Matrix n n 𝕜} (hA : A.PosDef) (hB : B.PosDe
228228
lemma PosDef.posDef_sqrt [DecidableEq n] {M : Matrix n n 𝕜} (hM : M.PosDef) :
229229
PosDef (CFC.sqrt M) := hM.isStrictlyPositive.sqrt.posDef
230230

231+
section kronecker
232+
variable {m : Type*} [Fintype m]
233+
234+
open scoped Kronecker
235+
236+
/-- The kronecker product of two positive semi-definite matrices is positive semi-definite. -/
237+
theorem PosSemidef.kronecker {x : Matrix n n 𝕜} {y : Matrix m m 𝕜}
238+
(hx : x.PosSemidef) (hy : y.PosSemidef) : (x ⊗ₖ y).PosSemidef := by
239+
classical
240+
obtain ⟨a, rfl⟩ := CStarAlgebra.nonneg_iff_eq_star_mul_self.mp hx.nonneg
241+
obtain ⟨b, rfl⟩ := CStarAlgebra.nonneg_iff_eq_star_mul_self.mp hy.nonneg
242+
simpa [mul_kronecker_mul, ← conjTranspose_kronecker, star_eq_conjTranspose] using
243+
posSemidef_conjTranspose_mul_self _
244+
245+
open Matrix in
246+
/-- The kronecker of two positive definite matrices is positive definite. -/
247+
theorem PosDef.kronecker {x : Matrix n n 𝕜} {y : Matrix m m 𝕜}
248+
(hx : x.PosDef) (hy : y.PosDef) : (x ⊗ₖ y).PosDef := by
249+
classical
250+
exact hx.posSemidef.kronecker hy.posSemidef |>.posDef_iff_isUnit.mpr <|
251+
hx.isUnit.kronecker hy.isUnit
252+
253+
end kronecker
254+
231255
/--
232256
A matrix is positive definite if and only if it has the form `Bᴴ * B` for some invertible `B`.
233257
-/

Mathlib/LinearAlgebra/Matrix/GeneralLinearGroup/Defs.lean

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,24 @@ lemma coe_map_inv_mul_map (g : GL n R) : g.val⁻¹.map f * g.val.map f = 1 := b
181181
rw [← Matrix.map_mul]
182182
simp only [isUnits_det_units, nonsing_inv_mul, map_zero, map_one, Matrix.map_one]
183183

184+
section kronecker
185+
variable {R m : Type*} [CommSemiring R] [Fintype m] [DecidableEq m]
186+
187+
open scoped Kronecker
188+
189+
/-- The invertible kronecker matrix of invertible matrices. -/
190+
protected def kronecker (x : GL n R) (y : GL m R) : GL (n × m) R where
191+
val := x ⊗ₖ y
192+
inv := ↑x⁻¹ ⊗ₖ ↑y⁻¹
193+
val_inv := by simp only [← mul_kronecker_mul, Units.mul_inv, one_kronecker_one]
194+
inv_val := by simp only [← mul_kronecker_mul, Units.inv_mul, one_kronecker_one]
195+
196+
theorem _root_.Matrix.IsUnit.kronecker {x : Matrix n n R} {y : Matrix m m R}
197+
(hx : IsUnit x) (hy : IsUnit y) : IsUnit (x ⊗ₖ y) :=
198+
GeneralLinearGroup.kronecker hx.unit hy.unit |>.isUnit
199+
200+
end kronecker
201+
184202
end GeneralLinearGroup
185203

186204
namespace SpecialLinearGroup

Mathlib/LinearAlgebra/Matrix/Hermitian.lean

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,11 @@ instance (A : Matrix n n α) [Decidable (Aᴴ = A)] : Decidable (IsHermitian A)
4545

4646
theorem IsHermitian.eq {A : Matrix n n α} (h : A.IsHermitian) : Aᴴ = A := h
4747

48-
protected theorem IsHermitian.isSelfAdjoint {A : Matrix n n α} (h : A.IsHermitian) :
49-
IsSelfAdjoint A := h
48+
theorem isHermitian_iff_isSelfAdjoint {A : Matrix n n α} :
49+
A.IsHermitian ↔ IsSelfAdjoint A := Iff.rfl
50+
51+
protected alias ⟨IsHermitian.isSelfAdjoint, _root_.IsSelfAdjoint.isHermitian⟩ :=
52+
isHermitian_iff_isSelfAdjoint
5053

5154
theorem IsHermitian.ext {A : Matrix n n α} : (∀ i j, star (A j i) = A i j) → A.IsHermitian := by
5255
intro h; ext i j; exact h i j

Mathlib/LinearAlgebra/Matrix/PosDef.lean

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,31 @@ theorem PosSemidef.trace_eq_zero_iff {A : Matrix n n 𝕜} (hA : A.PosSemidef) :
249249
(by simpa using hA.eigenvalues_nonneg), Finset.mem_univ, true_imp_iff] at h
250250
exact funext_iff.eq ▸ hA.isHermitian.eigenvalues_eq_zero_iff.mp <| h
251251

252+
section conjugate
253+
variable [DecidableEq n] {U x : Matrix n n R}
254+
255+
/-- For an invertible matrix `U`, `star U * x * U` is positive semi-definite iff `x` is.
256+
This works on any ⋆-ring with a partial order.
257+
258+
See `IsUnit.conjugate_nonneg_iff'` for a similar statement for star-ordered rings. -/
259+
theorem IsUnit.posSemidef_conjugate_iff' (hU : IsUnit U) :
260+
PosSemidef (star U * x * U) ↔ x.PosSemidef := by
261+
simp_rw [PosSemidef, isHermitian_iff_isSelfAdjoint, hU.isSelfAdjoint_conjugate_iff',
262+
and_congr_right_iff, ← mulVec_mulVec, dotProduct_mulVec, star_eq_conjTranspose, ← star_mulVec,
263+
← dotProduct_mulVec]
264+
obtain ⟨V, hV⟩ := hU.exists_right_inv
265+
exact fun _ => ⟨fun H y => by simpa [hV] using H (V *ᵥ y), fun H _ => H _⟩
266+
267+
open Matrix in
268+
/-- For an invertible matrix `U`, `U * x * star U` is positive semi-definite iff `x` is.
269+
This works on any ⋆-ring with a partial order.
270+
271+
See `IsUnit.conjugate_nonneg_iff` for a similar statement for star-ordered rings. -/
272+
theorem IsUnit.posSemidef_conjugate_iff (hU : IsUnit U) :
273+
PosSemidef (U * x * star U) ↔ x.PosSemidef := by simpa using hU.star.posSemidef_conjugate_iff'
274+
275+
end conjugate
276+
252277
/-- The matrix `vecMulVec a (star a)` is always positive semi-definite. -/
253278
theorem posSemidef_vecMulVec_self_star [StarOrderedRing R] (a : n → R) :
254279
(vecMulVec a (star a)).PosSemidef := by
@@ -470,6 +495,38 @@ theorem _root_.Matrix.posDef_inv_iff [DecidableEq n] {M : Matrix n n K} :
470495

471496
end Field
472497

498+
section conjugate
499+
variable [DecidableEq n] {x U : Matrix n n R}
500+
501+
/-- For an invertible matrix `U`, `star U * x * U` is positive definite iff `x` is.
502+
This works on any ⋆-ring with a partial order.
503+
504+
See `IsUnit.isStrictlyPositive_conjugate_iff'` for a similar statement for star-ordered rings.
505+
For matrices, positive definiteness is equivalent to strict positivity when the underlying field is
506+
`ℝ` or `ℂ` (see `Matrix.isStrictlyPositive_iff_posDef`). -/
507+
theorem _root_.Matrix.IsUnit.posDef_conjugate_iff' (hU : IsUnit U) :
508+
PosDef (star U * x * U) ↔ x.PosDef := by
509+
simp_rw [PosDef, isHermitian_iff_isSelfAdjoint, hU.isSelfAdjoint_conjugate_iff',
510+
and_congr_right_iff, ← mulVec_mulVec, dotProduct_mulVec, star_eq_conjTranspose, ← star_mulVec,
511+
← dotProduct_mulVec]
512+
obtain ⟨V, hV, hV2⟩ := isUnit_iff_exists.mp hU
513+
have hV3 (y : n → R) (hy : y ≠ 0) : U *ᵥ y ≠ 0 := fun h => by simpa [hy, hV2] using congr(V *ᵥ $h)
514+
have hV4 (y : n → R) (hy : y ≠ 0) : V *ᵥ y ≠ 0 := fun h => by simpa [hy, hV] using congr(U *ᵥ $h)
515+
exact fun _ => ⟨fun h x hx => by simpa [hV] using h _ (hV4 _ hx), fun h x hx => h _ (hV3 _ hx)⟩
516+
517+
open Matrix in
518+
/-- For an invertible matrix `U`, `U * x * star U` is positive definite iff `x` is.
519+
This works on any ⋆-ring with a partial order.
520+
521+
See `IsUnit.isStrictlyPositive_conjugate_iff` for a similar statement for star-ordered rings.
522+
For matrices, positive definiteness is equivalent to strict positivity when the underlying field is
523+
`ℝ` or `ℂ` (see `Matrix.isStrictlyPositive_iff_posDef`). -/
524+
theorem _root_.Matrix.IsUnit.posDef_conjugate_iff (hU : IsUnit U) :
525+
PosDef (U * x * star U) ↔ x.PosDef := by
526+
simpa using hU.star.posDef_conjugate_iff'
527+
528+
end conjugate
529+
473530
section SchurComplement
474531

475532
variable [StarOrderedRing R']

0 commit comments

Comments
 (0)