linear_algebra.matrix.schur_complement
⟷
Mathlib.LinearAlgebra.Matrix.SchurComplement
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -62,7 +62,7 @@ theorem fromBlocks_eq_of_invertible₁₁ (A : Matrix m m α) (B : Matrix m n α
by
simp only [from_blocks_multiply, Matrix.mul_zero, Matrix.zero_mul, add_zero, zero_add,
Matrix.one_mul, Matrix.mul_one, invOf_mul_self, Matrix.mul_invOf_self_assoc,
- Matrix.mul_invOf_mul_self_cancel, Matrix.mul_assoc, add_sub_cancel'_right]
+ Matrix.mul_invOf_mul_self_cancel, Matrix.mul_assoc, add_sub_cancel]
#align matrix.from_blocks_eq_of_invertible₁₁ Matrix.fromBlocks_eq_of_invertible₁₁
-/
@@ -541,11 +541,11 @@ end CommRing
/-! ### Lemmas about `ℝ` and `ℂ`-/
-section IsROrC
+section RCLike
open scoped Matrix
-variable {𝕜 : Type _} [IsROrC 𝕜]
+variable {𝕜 : Type _} [RCLike 𝕜]
scoped infixl:65 " ⊕ᵥ " => Sum.elim
@@ -645,7 +645,7 @@ theorem PosSemidef.fromBlocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A :
#align matrix.pos_semidef.from_blocks₂₂ Matrix.PosSemidef.fromBlocks₂₂
-/
-end IsROrC
+end RCLike
end Matrix
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -141,7 +141,7 @@ def invertibleOfFromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m
invertibleOfLeftInverse _ (⅟ (fromBlocks A B 0 D)).toBlocks₁₁ <|
by
have := invOf_mul_self (from_blocks A B 0 D)
- rw [← from_blocks_to_blocks (⅟ (from_blocks A B 0 D)), from_blocks_multiply] at this
+ rw [← from_blocks_to_blocks (⅟ (from_blocks A B 0 D)), from_blocks_multiply] at this
replace := congr_arg Matrix.toBlocks₁₁ this
simpa only [Matrix.toBlocks_fromBlocks₁₁, Matrix.mul_zero, add_zero, ← from_blocks_one] using
this
@@ -149,7 +149,7 @@ def invertibleOfFromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m
invertibleOfRightInverse _ (⅟ (fromBlocks A B 0 D)).toBlocks₂₂ <|
by
have := mul_invOf_self (from_blocks A B 0 D)
- rw [← from_blocks_to_blocks (⅟ (from_blocks A B 0 D)), from_blocks_multiply] at this
+ rw [← from_blocks_to_blocks (⅟ (from_blocks A B 0 D)), from_blocks_multiply] at this
replace := congr_arg Matrix.toBlocks₂₂ this
simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.zero_mul, zero_add, ← from_blocks_one] using
this
@@ -166,7 +166,7 @@ def invertibleOfFromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n
invertibleOfRightInverse _ (⅟ (fromBlocks A 0 C D)).toBlocks₁₁ <|
by
have := mul_invOf_self (from_blocks A 0 C D)
- rw [← from_blocks_to_blocks (⅟ (from_blocks A 0 C D)), from_blocks_multiply] at this
+ rw [← from_blocks_to_blocks (⅟ (from_blocks A 0 C D)), from_blocks_multiply] at this
replace := congr_arg Matrix.toBlocks₁₁ this
simpa only [Matrix.toBlocks_fromBlocks₁₁, Matrix.zero_mul, add_zero, ← from_blocks_one] using
this
@@ -174,7 +174,7 @@ def invertibleOfFromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n
invertibleOfLeftInverse _ (⅟ (fromBlocks A 0 C D)).toBlocks₂₂ <|
by
have := invOf_mul_self (from_blocks A 0 C D)
- rw [← from_blocks_to_blocks (⅟ (from_blocks A 0 C D)), from_blocks_multiply] at this
+ rw [← from_blocks_to_blocks (⅟ (from_blocks A 0 C D)), from_blocks_multiply] at this
replace := congr_arg Matrix.toBlocks₂₂ this
simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.mul_zero, zero_add, ← from_blocks_one] using
this
@@ -620,7 +620,7 @@ theorem PosSemidef.fromBlocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A :
· refine' fun h => ⟨h.1, fun x => _⟩
have := h.2 (-(A⁻¹ ⬝ B).mulVec x ⊕ᵥ x)
rw [dot_product_mul_vec, schur_complement_eq₁₁ B D _ _ hA.1, neg_add_self, dot_product_zero,
- zero_add] at this
+ zero_add] at this
rw [dot_product_mul_vec]; exact this
· refine' fun h => ⟨h.1, fun x => _⟩
rw [dot_product_mul_vec, ← Sum.elim_comp_inl_inr x, schur_complement_eq₁₁ B D _ _ hA.1, map_add]
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,9 +3,9 @@ Copyright (c) 2022 Alexander Bentkamp. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Alexander Bentkamp, Eric Wieser, Jeremy Avigad, Johan Commelin
-/
-import Mathbin.Data.Matrix.Invertible
-import Mathbin.LinearAlgebra.Matrix.NonsingularInverse
-import Mathbin.LinearAlgebra.Matrix.PosDef
+import Data.Matrix.Invertible
+import LinearAlgebra.Matrix.NonsingularInverse
+import LinearAlgebra.Matrix.PosDef
#align_import linear_algebra.matrix.schur_complement from "leanprover-community/mathlib"@"1a51edf13debfcbe223fa06b1cb353b9ed9751cc"
mathlib commit https://github.com/leanprover-community/mathlib/commit/32a7e535287f9c73f2e4d2aef306a39190f0b504
@@ -61,7 +61,7 @@ theorem fromBlocks_eq_of_invertible₁₁ (A : Matrix m m α) (B : Matrix m n α
fromBlocks 1 (⅟ A ⬝ B) 0 1 :=
by
simp only [from_blocks_multiply, Matrix.mul_zero, Matrix.zero_mul, add_zero, zero_add,
- Matrix.one_mul, Matrix.mul_one, Matrix.invOf_mul_self, Matrix.mul_invOf_self_assoc,
+ Matrix.one_mul, Matrix.mul_one, invOf_mul_self, Matrix.mul_invOf_self_assoc,
Matrix.mul_invOf_mul_self_cancel, Matrix.mul_assoc, add_sub_cancel'_right]
#align matrix.from_blocks_eq_of_invertible₁₁ Matrix.fromBlocks_eq_of_invertible₁₁
-/
@@ -92,7 +92,7 @@ def fromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D :
[Invertible A] [Invertible D] : Invertible (fromBlocks A B 0 D) :=
invertibleOfLeftInverse _ (fromBlocks (⅟ A) (-⅟ A ⬝ B ⬝ ⅟ D) 0 (⅟ D)) <| by
simp_rw [from_blocks_multiply, Matrix.mul_zero, Matrix.zero_mul, zero_add, add_zero,
- Matrix.neg_mul, Matrix.invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_right_neg,
+ Matrix.neg_mul, invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_right_neg,
from_blocks_one]
#align matrix.from_blocks_zero₂₁_invertible Matrix.fromBlocksZero₂₁Invertible
-/
@@ -106,7 +106,7 @@ def fromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n m α) (D :
(⅟ D)) <|-- a symmetry argument is more work than just copying the proof
by
simp_rw [from_blocks_multiply, Matrix.mul_zero, Matrix.zero_mul, zero_add, add_zero,
- Matrix.neg_mul, Matrix.invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_left_neg,
+ Matrix.neg_mul, invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_left_neg,
from_blocks_one]
#align matrix.from_blocks_zero₁₂_invertible Matrix.fromBlocksZero₁₂Invertible
-/
@@ -140,7 +140,7 @@ def invertibleOfFromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m
fst :=
invertibleOfLeftInverse _ (⅟ (fromBlocks A B 0 D)).toBlocks₁₁ <|
by
- have := Matrix.invOf_mul_self (from_blocks A B 0 D)
+ have := invOf_mul_self (from_blocks A B 0 D)
rw [← from_blocks_to_blocks (⅟ (from_blocks A B 0 D)), from_blocks_multiply] at this
replace := congr_arg Matrix.toBlocks₁₁ this
simpa only [Matrix.toBlocks_fromBlocks₁₁, Matrix.mul_zero, add_zero, ← from_blocks_one] using
@@ -148,7 +148,7 @@ def invertibleOfFromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m
snd :=
invertibleOfRightInverse _ (⅟ (fromBlocks A B 0 D)).toBlocks₂₂ <|
by
- have := Matrix.mul_invOf_self (from_blocks A B 0 D)
+ have := mul_invOf_self (from_blocks A B 0 D)
rw [← from_blocks_to_blocks (⅟ (from_blocks A B 0 D)), from_blocks_multiply] at this
replace := congr_arg Matrix.toBlocks₂₂ this
simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.zero_mul, zero_add, ← from_blocks_one] using
@@ -165,7 +165,7 @@ def invertibleOfFromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n
fst :=
invertibleOfRightInverse _ (⅟ (fromBlocks A 0 C D)).toBlocks₁₁ <|
by
- have := Matrix.mul_invOf_self (from_blocks A 0 C D)
+ have := mul_invOf_self (from_blocks A 0 C D)
rw [← from_blocks_to_blocks (⅟ (from_blocks A 0 C D)), from_blocks_multiply] at this
replace := congr_arg Matrix.toBlocks₁₁ this
simpa only [Matrix.toBlocks_fromBlocks₁₁, Matrix.zero_mul, add_zero, ← from_blocks_one] using
@@ -173,7 +173,7 @@ def invertibleOfFromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n
snd :=
invertibleOfLeftInverse _ (⅟ (fromBlocks A 0 C D)).toBlocks₂₂ <|
by
- have := Matrix.invOf_mul_self (from_blocks A 0 C D)
+ have := invOf_mul_self (from_blocks A 0 C D)
rw [← from_blocks_to_blocks (⅟ (from_blocks A 0 C D)), from_blocks_multiply] at this
replace := congr_arg Matrix.toBlocks₂₂ this
simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.mul_zero, zero_add, ← from_blocks_one] using
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,16 +2,13 @@
Copyright (c) 2022 Alexander Bentkamp. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Alexander Bentkamp, Eric Wieser, Jeremy Avigad, Johan Commelin
-
-! This file was ported from Lean 3 source module linear_algebra.matrix.schur_complement
-! leanprover-community/mathlib commit 1a51edf13debfcbe223fa06b1cb353b9ed9751cc
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Data.Matrix.Invertible
import Mathbin.LinearAlgebra.Matrix.NonsingularInverse
import Mathbin.LinearAlgebra.Matrix.PosDef
+#align_import linear_algebra.matrix.schur_complement from "leanprover-community/mathlib"@"1a51edf13debfcbe223fa06b1cb353b9ed9751cc"
+
/-! # 2×2 block matrices and the Schur complement
> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
mathlib commit https://github.com/leanprover-community/mathlib/commit/1a51edf13debfcbe223fa06b1cb353b9ed9751cc
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Alexander Bentkamp, Eric Wieser, Jeremy Avigad, Johan Commelin
! This file was ported from Lean 3 source module linear_algebra.matrix.schur_complement
-! leanprover-community/mathlib commit a176cb1219e300e85793d44583dede42377b51af
+! leanprover-community/mathlib commit 1a51edf13debfcbe223fa06b1cb353b9ed9751cc
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -14,6 +14,9 @@ import Mathbin.LinearAlgebra.Matrix.PosDef
/-! # 2×2 block matrices and the Schur complement
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
This file proves properties of 2×2 block matrices `[A B; C D]` that relate to the Schur complement
`D - C⬝A⁻¹⬝B`.
mathlib commit https://github.com/leanprover-community/mathlib/commit/5dc6092d09e5e489106865241986f7f2ad28d4c8
@@ -51,6 +51,7 @@ variable [DecidableEq l] [DecidableEq m] [DecidableEq n]
variable [CommRing α]
+#print Matrix.fromBlocks_eq_of_invertible₁₁ /-
/-- LDU decomposition of a block matrix with an invertible top-left corner, using the
Schur complement. -/
theorem fromBlocks_eq_of_invertible₁₁ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix l m α)
@@ -63,7 +64,9 @@ theorem fromBlocks_eq_of_invertible₁₁ (A : Matrix m m α) (B : Matrix m n α
Matrix.one_mul, Matrix.mul_one, Matrix.invOf_mul_self, Matrix.mul_invOf_self_assoc,
Matrix.mul_invOf_mul_self_cancel, Matrix.mul_assoc, add_sub_cancel'_right]
#align matrix.from_blocks_eq_of_invertible₁₁ Matrix.fromBlocks_eq_of_invertible₁₁
+-/
+#print Matrix.fromBlocks_eq_of_invertible₂₂ /-
/-- LDU decomposition of a block matrix with an invertible bottom-right corner, using the
Schur complement. -/
theorem fromBlocks_eq_of_invertible₂₂ (A : Matrix l m α) (B : Matrix l n α) (C : Matrix n m α)
@@ -76,12 +79,14 @@ theorem fromBlocks_eq_of_invertible₂₂ (A : Matrix l m α) (B : Matrix l n α
submatrix_mul_equiv _ _ _ (Equiv.sumComm n l), Equiv.sumComm_apply,
from_blocks_submatrix_sum_swap_sum_swap] using from_blocks_eq_of_invertible₁₁ D C B A
#align matrix.from_blocks_eq_of_invertible₂₂ Matrix.fromBlocks_eq_of_invertible₂₂
+-/
section Triangular
/-! #### Block triangular matrices -/
+#print Matrix.fromBlocksZero₂₁Invertible /-
/-- An upper-block-triangular matrix is invertible if its diagonal is. -/
def fromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
[Invertible A] [Invertible D] : Invertible (fromBlocks A B 0 D) :=
@@ -90,7 +95,9 @@ def fromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D :
Matrix.neg_mul, Matrix.invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_right_neg,
from_blocks_one]
#align matrix.from_blocks_zero₂₁_invertible Matrix.fromBlocksZero₂₁Invertible
+-/
+#print Matrix.fromBlocksZero₁₂Invertible /-
/-- A lower-block-triangular matrix is invertible if its diagonal is. -/
def fromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
[Invertible A] [Invertible D] : Invertible (fromBlocks A 0 C D) :=
@@ -102,7 +109,9 @@ def fromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n m α) (D :
Matrix.neg_mul, Matrix.invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_left_neg,
from_blocks_one]
#align matrix.from_blocks_zero₁₂_invertible Matrix.fromBlocksZero₁₂Invertible
+-/
+#print Matrix.invOf_fromBlocks_zero₂₁_eq /-
theorem invOf_fromBlocks_zero₂₁_eq (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
[Invertible A] [Invertible D] [Invertible (fromBlocks A B 0 D)] :
⅟ (fromBlocks A B 0 D) = fromBlocks (⅟ A) (-⅟ A ⬝ B ⬝ ⅟ D) 0 (⅟ D) :=
@@ -110,7 +119,9 @@ theorem invOf_fromBlocks_zero₂₁_eq (A : Matrix m m α) (B : Matrix m n α) (
letI := from_blocks_zero₂₁_invertible A B D
convert (rfl : ⅟ (from_blocks A B 0 D) = _)
#align matrix.inv_of_from_blocks_zero₂₁_eq Matrix.invOf_fromBlocks_zero₂₁_eq
+-/
+#print Matrix.invOf_fromBlocks_zero₁₂_eq /-
theorem invOf_fromBlocks_zero₁₂_eq (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
[Invertible A] [Invertible D] [Invertible (fromBlocks A 0 C D)] :
⅟ (fromBlocks A 0 C D) = fromBlocks (⅟ A) 0 (-⅟ D ⬝ C ⬝ ⅟ A) (⅟ D) :=
@@ -118,7 +129,9 @@ theorem invOf_fromBlocks_zero₁₂_eq (A : Matrix m m α) (C : Matrix n m α) (
letI := from_blocks_zero₁₂_invertible A C D
convert (rfl : ⅟ (from_blocks A 0 C D) = _)
#align matrix.inv_of_from_blocks_zero₁₂_eq Matrix.invOf_fromBlocks_zero₁₂_eq
+-/
+#print Matrix.invertibleOfFromBlocksZero₂₁Invertible /-
/-- Both diagonal entries of an invertible upper-block-triangular matrix are invertible (by reading
off the diagonal entries of the inverse). -/
def invertibleOfFromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
@@ -141,7 +154,9 @@ def invertibleOfFromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m
simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.zero_mul, zero_add, ← from_blocks_one] using
this
#align matrix.invertible_of_from_blocks_zero₂₁_invertible Matrix.invertibleOfFromBlocksZero₂₁Invertible
+-/
+#print Matrix.invertibleOfFromBlocksZero₁₂Invertible /-
/-- Both diagonal entries of an invertible lower-block-triangular matrix are invertible (by reading
off the diagonal entries of the inverse). -/
def invertibleOfFromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
@@ -164,7 +179,9 @@ def invertibleOfFromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n
simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.mul_zero, zero_add, ← from_blocks_one] using
this
#align matrix.invertible_of_from_blocks_zero₁₂_invertible Matrix.invertibleOfFromBlocksZero₁₂Invertible
+-/
+#print Matrix.fromBlocksZero₂₁InvertibleEquiv /-
/-- `invertible_of_from_blocks_zero₂₁_invertible` and `from_blocks_zero₂₁_invertible` form
an equivalence. -/
def fromBlocksZero₂₁InvertibleEquiv (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α) :
@@ -175,7 +192,9 @@ def fromBlocksZero₂₁InvertibleEquiv (A : Matrix m m α) (B : Matrix m n α)
left_inv _ := Subsingleton.elim _ _
right_inv _ := Subsingleton.elim _ _
#align matrix.from_blocks_zero₂₁_invertible_equiv Matrix.fromBlocksZero₂₁InvertibleEquiv
+-/
+#print Matrix.fromBlocksZero₁₂InvertibleEquiv /-
/-- `invertible_of_from_blocks_zero₁₂_invertible` and `from_blocks_zero₁₂_invertible` form
an equivalence. -/
def fromBlocksZero₁₂InvertibleEquiv (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α) :
@@ -186,7 +205,9 @@ def fromBlocksZero₁₂InvertibleEquiv (A : Matrix m m α) (C : Matrix n m α)
left_inv _ := Subsingleton.elim _ _
right_inv _ := Subsingleton.elim _ _
#align matrix.from_blocks_zero₁₂_invertible_equiv Matrix.fromBlocksZero₁₂InvertibleEquiv
+-/
+#print Matrix.isUnit_fromBlocks_zero₂₁ /-
/-- An upper block-triangular matrix is invertible iff both elements of its diagonal are.
This is a propositional form of `matrix.from_blocks_zero₂₁_invertible_equiv`. -/
@@ -196,7 +217,9 @@ theorem isUnit_fromBlocks_zero₂₁ {A : Matrix m m α} {B : Matrix m n α} {D
simp only [← nonempty_invertible_iff_isUnit, ← nonempty_prod,
(from_blocks_zero₂₁_invertible_equiv _ _ _).nonempty_congr]
#align matrix.is_unit_from_blocks_zero₂₁ Matrix.isUnit_fromBlocks_zero₂₁
+-/
+#print Matrix.isUnit_fromBlocks_zero₁₂ /-
/-- A lower block-triangular matrix is invertible iff both elements of its diagonal are.
This is a propositional form of `matrix.from_blocks_zero₁₂_invertible_equiv` forms an `iff`. -/
@@ -206,7 +229,9 @@ theorem isUnit_fromBlocks_zero₁₂ {A : Matrix m m α} {C : Matrix n m α} {D
simp only [← nonempty_invertible_iff_isUnit, ← nonempty_prod,
(from_blocks_zero₁₂_invertible_equiv _ _ _).nonempty_congr]
#align matrix.is_unit_from_blocks_zero₁₂ Matrix.isUnit_fromBlocks_zero₁₂
+-/
+#print Matrix.inv_fromBlocks_zero₂₁_of_isUnit_iff /-
/-- An expression for the inverse of an upper block-triangular matrix, when either both elements of
diagonal are invertible, or both are not. -/
theorem inv_fromBlocks_zero₂₁_of_isUnit_iff (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
@@ -224,7 +249,9 @@ theorem inv_fromBlocks_zero₂₁_of_isUnit_iff (A : Matrix m m α) (B : Matrix
simp_rw [nonsing_inv_eq_ring_inverse, Ring.inverse_non_unit _ hA, Ring.inverse_non_unit _ hD,
Ring.inverse_non_unit _ this, Matrix.zero_mul, neg_zero, from_blocks_zero]
#align matrix.inv_from_blocks_zero₂₁_of_is_unit_iff Matrix.inv_fromBlocks_zero₂₁_of_isUnit_iff
+-/
+#print Matrix.inv_fromBlocks_zero₁₂_of_isUnit_iff /-
/-- An expression for the inverse of a lower block-triangular matrix, when either both elements of
diagonal are invertible, or both are not. -/
theorem inv_fromBlocks_zero₁₂_of_isUnit_iff (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
@@ -242,6 +269,7 @@ theorem inv_fromBlocks_zero₁₂_of_isUnit_iff (A : Matrix m m α) (C : Matrix
simp_rw [nonsing_inv_eq_ring_inverse, Ring.inverse_non_unit _ hA, Ring.inverse_non_unit _ hD,
Ring.inverse_non_unit _ this, Matrix.zero_mul, neg_zero, from_blocks_zero]
#align matrix.inv_from_blocks_zero₁₂_of_is_unit_iff Matrix.inv_fromBlocks_zero₁₂_of_isUnit_iff
+-/
end Triangular
@@ -253,6 +281,7 @@ section Block
/-! #### General 2×2 block matrices-/
+#print Matrix.fromBlocks₂₂Invertible /-
/-- A block matrix is invertible if the bottom right corner and the corresponding schur complement
is. -/
def fromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
@@ -283,7 +312,9 @@ def fromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matr
Matrix.mul_zero, add_zero, zero_add, neg_zero, Matrix.mul_neg, Matrix.neg_mul, neg_neg, ←
Matrix.mul_assoc, add_comm]
#align matrix.from_blocks₂₂_invertible Matrix.fromBlocks₂₂Invertible
+-/
+#print Matrix.fromBlocks₁₁Invertible /-
/-- A block matrix is invertible if the top left corner and the corresponding schur complement
is. -/
def fromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
@@ -301,8 +332,10 @@ def fromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matr
(from_blocks_submatrix_sum_swap_sum_swap _ _ _ _).symm
(from_blocks_submatrix_sum_swap_sum_swap _ _ _ _).symm
#align matrix.from_blocks₁₁_invertible Matrix.fromBlocks₁₁Invertible
+-/
-theorem invOf_from_blocks₂₂_eq (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+#print Matrix.invOf_fromBlocks₂₂_eq /-
+theorem invOf_fromBlocks₂₂_eq (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
(D : Matrix n n α) [Invertible D] [Invertible (A - B ⬝ ⅟ D ⬝ C)]
[Invertible (fromBlocks A B C D)] :
⅟ (fromBlocks A B C D) =
@@ -311,9 +344,11 @@ theorem invOf_from_blocks₂₂_eq (A : Matrix m m α) (B : Matrix m n α) (C :
by
letI := from_blocks₂₂_invertible A B C D
convert (rfl : ⅟ (from_blocks A B C D) = _)
-#align matrix.inv_of_from_blocks₂₂_eq Matrix.invOf_from_blocks₂₂_eq
+#align matrix.inv_of_from_blocks₂₂_eq Matrix.invOf_fromBlocks₂₂_eq
+-/
-theorem invOf_from_blocks₁₁_eq (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+#print Matrix.invOf_fromBlocks₁₁_eq /-
+theorem invOf_fromBlocks₁₁_eq (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
(D : Matrix n n α) [Invertible A] [Invertible (D - C ⬝ ⅟ A ⬝ B)]
[Invertible (fromBlocks A B C D)] :
⅟ (fromBlocks A B C D) =
@@ -322,8 +357,10 @@ theorem invOf_from_blocks₁₁_eq (A : Matrix m m α) (B : Matrix m n α) (C :
by
letI := from_blocks₁₁_invertible A B C D
convert (rfl : ⅟ (from_blocks A B C D) = _)
-#align matrix.inv_of_from_blocks₁₁_eq Matrix.invOf_from_blocks₁₁_eq
+#align matrix.inv_of_from_blocks₁₁_eq Matrix.invOf_fromBlocks₁₁_eq
+-/
+#print Matrix.invertibleOfFromBlocks₂₂Invertible /-
/-- If a block matrix is invertible and so is its bottom left element, then so is the corresponding
Schur complement. -/
def invertibleOfFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
@@ -342,7 +379,9 @@ def invertibleOfFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n
refine' (iBD.matrix_mul_left _).symm _
refine' (iDC.matrix_mul_right _).symm iBDC
#align matrix.invertible_of_from_blocks₂₂_invertible Matrix.invertibleOfFromBlocks₂₂Invertible
+-/
+#print Matrix.invertibleOfFromBlocks₁₁Invertible /-
/-- If a block matrix is invertible and so is its bottom left element, then so is the corresponding
Schur complement. -/
def invertibleOfFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
@@ -355,7 +394,9 @@ def invertibleOfFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n
letI iDCBA := iABCD'.copy _ (from_blocks_submatrix_sum_swap_sum_swap _ _ _ _).symm
refine' invertible_of_from_blocks₂₂_invertible D C B A
#align matrix.invertible_of_from_blocks₁₁_invertible Matrix.invertibleOfFromBlocks₁₁Invertible
+-/
+#print Matrix.invertibleEquivFromBlocks₂₂Invertible /-
/-- `matrix.invertible_of_from_blocks₂₂_invertible` and `matrix.from_blocks₂₂_invertible` as an
equivalence. -/
def invertibleEquivFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
@@ -367,7 +408,9 @@ def invertibleEquivFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m
left_inv iABCD := Subsingleton.elim _ _
right_inv i_schur := Subsingleton.elim _ _
#align matrix.invertible_equiv_from_blocks₂₂_invertible Matrix.invertibleEquivFromBlocks₂₂Invertible
+-/
+#print Matrix.invertibleEquivFromBlocks₁₁Invertible /-
/-- `matrix.invertible_of_from_blocks₁₁_invertible` and `matrix.from_blocks₁₁_invertible` as an
equivalence. -/
def invertibleEquivFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
@@ -379,7 +422,9 @@ def invertibleEquivFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m
left_inv iABCD := Subsingleton.elim _ _
right_inv i_schur := Subsingleton.elim _ _
#align matrix.invertible_equiv_from_blocks₁₁_invertible Matrix.invertibleEquivFromBlocks₁₁Invertible
+-/
+#print Matrix.isUnit_fromBlocks_iff_of_invertible₂₂ /-
/-- If the bottom-left element of a block matrix is invertible, then the whole matrix is invertible
iff the corresponding schur complement is. -/
theorem isUnit_fromBlocks_iff_of_invertible₂₂ {A : Matrix m m α} {B : Matrix m n α}
@@ -388,7 +433,9 @@ theorem isUnit_fromBlocks_iff_of_invertible₂₂ {A : Matrix m m α} {B : Matri
simp only [← nonempty_invertible_iff_isUnit,
(invertible_equiv_from_blocks₂₂_invertible A B C D).nonempty_congr]
#align matrix.is_unit_from_blocks_iff_of_invertible₂₂ Matrix.isUnit_fromBlocks_iff_of_invertible₂₂
+-/
+#print Matrix.isUnit_fromBlocks_iff_of_invertible₁₁ /-
/-- If the top-right element of a block matrix is invertible, then the whole matrix is invertible
iff the corresponding schur complement is. -/
theorem isUnit_fromBlocks_iff_of_invertible₁₁ {A : Matrix m m α} {B : Matrix m n α}
@@ -397,6 +444,7 @@ theorem isUnit_fromBlocks_iff_of_invertible₁₁ {A : Matrix m m α} {B : Matri
simp only [← nonempty_invertible_iff_isUnit,
(invertible_equiv_from_blocks₁₁_invertible A B C D).nonempty_congr]
#align matrix.is_unit_from_blocks_iff_of_invertible₁₁ Matrix.isUnit_fromBlocks_iff_of_invertible₁₁
+-/
end Block
@@ -405,15 +453,17 @@ end Block
section Det
+#print Matrix.det_fromBlocks₁₁ /-
/-- Determinant of a 2×2 block matrix, expanded around an invertible top left element in terms of
the Schur complement. -/
-theorem det_from_blocks₁₁ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
- (D : Matrix n n α) [Invertible A] :
- (Matrix.fromBlocks A B C D).det = det A * det (D - C ⬝ ⅟ A ⬝ B) := by
+theorem det_fromBlocks₁₁ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α)
+ [Invertible A] : (Matrix.fromBlocks A B C D).det = det A * det (D - C ⬝ ⅟ A ⬝ B) := by
rw [from_blocks_eq_of_invertible₁₁, det_mul, det_mul, det_from_blocks_zero₂₁,
det_from_blocks_zero₂₁, det_from_blocks_zero₁₂, det_one, det_one, one_mul, one_mul, mul_one]
-#align matrix.det_from_blocks₁₁ Matrix.det_from_blocks₁₁
+#align matrix.det_from_blocks₁₁ Matrix.det_fromBlocks₁₁
+-/
+#print Matrix.det_fromBlocks_one₁₁ /-
@[simp]
theorem det_fromBlocks_one₁₁ (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α) :
(Matrix.fromBlocks 1 B C D).det = det (D - C ⬝ B) :=
@@ -421,12 +471,13 @@ theorem det_fromBlocks_one₁₁ (B : Matrix m n α) (C : Matrix n m α) (D : Ma
haveI : Invertible (1 : Matrix m m α) := invertibleOne
rw [det_from_blocks₁₁, invOf_one, Matrix.mul_one, det_one, one_mul]
#align matrix.det_from_blocks_one₁₁ Matrix.det_fromBlocks_one₁₁
+-/
+#print Matrix.det_fromBlocks₂₂ /-
/-- Determinant of a 2×2 block matrix, expanded around an invertible bottom right element in terms
of the Schur complement. -/
-theorem det_from_blocks₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
- (D : Matrix n n α) [Invertible D] :
- (Matrix.fromBlocks A B C D).det = det D * det (A - B ⬝ ⅟ D ⬝ C) :=
+theorem det_fromBlocks₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α)
+ [Invertible D] : (Matrix.fromBlocks A B C D).det = det D * det (A - B ⬝ ⅟ D ⬝ C) :=
by
have :
from_blocks A B C D = (from_blocks D C B A).submatrix (Equiv.sumComm _ _) (Equiv.sumComm _ _) :=
@@ -434,8 +485,10 @@ theorem det_from_blocks₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matri
ext i j
cases i <;> cases j <;> rfl
rw [this, det_submatrix_equiv_self, det_from_blocks₁₁]
-#align matrix.det_from_blocks₂₂ Matrix.det_from_blocks₂₂
+#align matrix.det_from_blocks₂₂ Matrix.det_fromBlocks₂₂
+-/
+#print Matrix.det_fromBlocks_one₂₂ /-
@[simp]
theorem det_fromBlocks_one₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) :
(Matrix.fromBlocks A B C 1).det = det (A - B ⬝ C) :=
@@ -443,7 +496,9 @@ theorem det_fromBlocks_one₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Ma
haveI : Invertible (1 : Matrix n n α) := invertibleOne
rw [det_from_blocks₂₂, invOf_one, Matrix.mul_one, det_one, one_mul]
#align matrix.det_from_blocks_one₂₂ Matrix.det_fromBlocks_one₂₂
+-/
+#print Matrix.det_one_add_mul_comm /-
/-- The **Weinstein–Aronszajn identity**. Note the `1` on the LHS is of shape m×m, while the `1` on
the RHS is of shape n×n. -/
theorem det_one_add_mul_comm (A : Matrix m n α) (B : Matrix n m α) :
@@ -453,17 +508,23 @@ theorem det_one_add_mul_comm (A : Matrix m n α) (B : Matrix n m α) :
rw [det_from_blocks_one₂₂, Matrix.neg_mul, sub_neg_eq_add]
_ = det (1 + B ⬝ A) := by rw [det_from_blocks_one₁₁, Matrix.mul_neg, sub_neg_eq_add]
#align matrix.det_one_add_mul_comm Matrix.det_one_add_mul_comm
+-/
+#print Matrix.det_mul_add_one_comm /-
/-- Alternate statement of the **Weinstein–Aronszajn identity** -/
theorem det_mul_add_one_comm (A : Matrix m n α) (B : Matrix n m α) :
det (A ⬝ B + 1) = det (B ⬝ A + 1) := by rw [add_comm, det_one_add_mul_comm, add_comm]
#align matrix.det_mul_add_one_comm Matrix.det_mul_add_one_comm
+-/
+#print Matrix.det_one_sub_mul_comm /-
theorem det_one_sub_mul_comm (A : Matrix m n α) (B : Matrix n m α) :
det (1 - A ⬝ B) = det (1 - B ⬝ A) := by
rw [sub_eq_add_neg, ← Matrix.neg_mul, det_one_add_mul_comm, Matrix.mul_neg, ← sub_eq_add_neg]
#align matrix.det_one_sub_mul_comm Matrix.det_one_sub_mul_comm
+-/
+#print Matrix.det_one_add_col_mul_row /-
/-- A special case of the **Matrix determinant lemma** for when `A = I`.
TODO: show this more generally. -/
@@ -471,6 +532,7 @@ theorem det_one_add_col_mul_row (u v : m → α) : det (1 + col u ⬝ row v) = 1
rw [det_one_add_mul_comm, det_unique, Pi.add_apply, Pi.add_apply, Matrix.one_apply_eq,
Matrix.row_mul_col_apply]
#align matrix.det_one_add_col_mul_row Matrix.det_one_add_col_mul_row
+-/
end Det
@@ -487,6 +549,7 @@ variable {𝕜 : Type _} [IsROrC 𝕜]
scoped infixl:65 " ⊕ᵥ " => Sum.elim
+#print Matrix.schur_complement_eq₁₁ /-
theorem schur_complement_eq₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A : Matrix m m 𝕜}
(B : Matrix m n 𝕜) (D : Matrix n n 𝕜) (x : m → 𝕜) (y : n → 𝕜) [Invertible A]
(hA : A.IsHermitian) :
@@ -499,7 +562,9 @@ theorem schur_complement_eq₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A : M
conj_transpose_nonsing_inv, star_mul_vec]
abel
#align matrix.schur_complement_eq₁₁ Matrix.schur_complement_eq₁₁
+-/
+#print Matrix.schur_complement_eq₂₂ /-
theorem schur_complement_eq₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : Matrix m m 𝕜)
(B : Matrix m n 𝕜) {D : Matrix n n 𝕜} (x : m → 𝕜) (y : n → 𝕜) [Invertible D]
(hD : D.IsHermitian) :
@@ -512,8 +577,10 @@ theorem schur_complement_eq₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : M
conj_transpose_nonsing_inv, star_mul_vec]
abel
#align matrix.schur_complement_eq₂₂ Matrix.schur_complement_eq₂₂
+-/
-theorem IsHermitian.from_blocks₁₁ [Fintype m] [DecidableEq m] {A : Matrix m m 𝕜} (B : Matrix m n 𝕜)
+#print Matrix.IsHermitian.fromBlocks₁₁ /-
+theorem IsHermitian.fromBlocks₁₁ [Fintype m] [DecidableEq m] {A : Matrix m m 𝕜} (B : Matrix m n 𝕜)
(D : Matrix n n 𝕜) (hA : A.IsHermitian) :
(fromBlocks A B Bᴴ D).IsHermitian ↔ (D - Bᴴ ⬝ A⁻¹ ⬝ B).IsHermitian :=
by
@@ -529,18 +596,22 @@ theorem IsHermitian.from_blocks₁₁ [Fintype m] [DecidableEq m] {A : Matrix m
refine' ⟨hA, rfl, conj_transpose_conj_transpose B, _⟩
rw [← sub_add_cancel D]
apply is_hermitian.add h hBAB
-#align matrix.is_hermitian.from_blocks₁₁ Matrix.IsHermitian.from_blocks₁₁
+#align matrix.is_hermitian.from_blocks₁₁ Matrix.IsHermitian.fromBlocks₁₁
+-/
-theorem IsHermitian.from_blocks₂₂ [Fintype n] [DecidableEq n] (A : Matrix m m 𝕜) (B : Matrix m n 𝕜)
+#print Matrix.IsHermitian.fromBlocks₂₂ /-
+theorem IsHermitian.fromBlocks₂₂ [Fintype n] [DecidableEq n] (A : Matrix m m 𝕜) (B : Matrix m n 𝕜)
{D : Matrix n n 𝕜} (hD : D.IsHermitian) :
(fromBlocks A B Bᴴ D).IsHermitian ↔ (A - B ⬝ D⁻¹ ⬝ Bᴴ).IsHermitian :=
by
rw [← is_hermitian_submatrix_equiv (Equiv.sumComm n m), Equiv.sumComm_apply,
from_blocks_submatrix_sum_swap_sum_swap]
convert is_hermitian.from_blocks₁₁ _ _ hD <;> simp
-#align matrix.is_hermitian.from_blocks₂₂ Matrix.IsHermitian.from_blocks₂₂
+#align matrix.is_hermitian.from_blocks₂₂ Matrix.IsHermitian.fromBlocks₂₂
+-/
-theorem PosSemidef.from_blocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A : Matrix m m 𝕜}
+#print Matrix.PosSemidef.fromBlocks₁₁ /-
+theorem PosSemidef.fromBlocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A : Matrix m m 𝕜}
(B : Matrix m n 𝕜) (D : Matrix n n 𝕜) (hA : A.PosDef) [Invertible A] :
(fromBlocks A B Bᴴ D).PosSemidef ↔ (D - Bᴴ ⬝ A⁻¹ ⬝ B).PosSemidef :=
by
@@ -557,9 +628,11 @@ theorem PosSemidef.from_blocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A
· rw [← dot_product_mul_vec]
apply hA.pos_semidef.2
· rw [← dot_product_mul_vec]; apply h.2
-#align matrix.pos_semidef.from_blocks₁₁ Matrix.PosSemidef.from_blocks₁₁
+#align matrix.pos_semidef.from_blocks₁₁ Matrix.PosSemidef.fromBlocks₁₁
+-/
-theorem PosSemidef.from_blocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : Matrix m m 𝕜)
+#print Matrix.PosSemidef.fromBlocks₂₂ /-
+theorem PosSemidef.fromBlocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : Matrix m m 𝕜)
(B : Matrix m n 𝕜) {D : Matrix n n 𝕜} (hD : D.PosDef) [Invertible D] :
(fromBlocks A B Bᴴ D).PosSemidef ↔ (A - B ⬝ D⁻¹ ⬝ Bᴴ).PosSemidef :=
by
@@ -569,7 +642,8 @@ theorem PosSemidef.from_blocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A
first
| infer_instance
| simp
-#align matrix.pos_semidef.from_blocks₂₂ Matrix.PosSemidef.from_blocks₂₂
+#align matrix.pos_semidef.from_blocks₂₂ Matrix.PosSemidef.fromBlocks₂₂
+-/
end IsROrC
mathlib commit https://github.com/leanprover-community/mathlib/commit/728ef9dbb281241906f25cbeb30f90d83e0bb451
@@ -4,10 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Alexander Bentkamp, Eric Wieser, Jeremy Avigad, Johan Commelin
! This file was ported from Lean 3 source module linear_algebra.matrix.schur_complement
-! leanprover-community/mathlib commit 96aa788f3e443efb3dace8a634258a9259364f43
+! leanprover-community/mathlib commit a176cb1219e300e85793d44583dede42377b51af
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
+import Mathbin.Data.Matrix.Invertible
import Mathbin.LinearAlgebra.Matrix.NonsingularInverse
import Mathbin.LinearAlgebra.Matrix.PosDef
@@ -16,6 +17,11 @@ import Mathbin.LinearAlgebra.Matrix.PosDef
This file proves properties of 2×2 block matrices `[A B; C D]` that relate to the Schur complement
`D - C⬝A⁻¹⬝B`.
+Some of the results here generalize to 2×2 matrices in a category, rather than just a ring. A few
+results in this direction can be found in the the file `cateogry_theory.preadditive.biproducts`,
+especially the declarations `category_theory.biprod.gaussian` and `category_theory.biprod.iso_elim`.
+Compare with `matrix.invertible_of_from_blocks₁₁_invertible`.
+
## Main results
* `matrix.det_from_blocks₁₁`, `matrix.det_from_blocks₂₂`: determinant of a block matrix in terms of
@@ -239,6 +245,161 @@ theorem inv_fromBlocks_zero₁₂_of_isUnit_iff (A : Matrix m m α) (C : Matrix
end Triangular
+/-! ### 2×2 block matrices -/
+
+
+section Block
+
+/-! #### General 2×2 block matrices-/
+
+
+/-- A block matrix is invertible if the bottom right corner and the corresponding schur complement
+is. -/
+def fromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible D] [Invertible (A - B ⬝ ⅟ D ⬝ C)] :
+ Invertible (fromBlocks A B C D) :=
+ by
+ -- factor `from_blocks` via `from_blocks_eq_of_invertible₂₂`, and state the inverse we expect
+ refine'
+ Invertible.copy' _ _
+ (from_blocks (⅟ (A - B ⬝ ⅟ D ⬝ C)) (-⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ B ⬝ ⅟ D)
+ (-⅟ D ⬝ C ⬝ ⅟ (A - B ⬝ ⅟ D ⬝ C)) (⅟ D + ⅟ D ⬝ C ⬝ ⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ B ⬝ ⅟ D))
+ (from_blocks_eq_of_invertible₂₂ _ _ _ _) _
+ · -- the product is invertible because all the factors are
+ letI : Invertible (1 : Matrix n n α) := invertibleOne
+ letI : Invertible (1 : Matrix m m α) := invertibleOne
+ refine' Invertible.matrixMul _ (from_blocks_zero₁₂_invertible _ _ _)
+ exact
+ Invertible.matrixMul (from_blocks_zero₂₁_invertible _ _ _)
+ (from_blocks_zero₂₁_invertible _ _ _)
+ · -- unfold the `invertible` instances to get the raw factors
+ show
+ _ =
+ from_blocks 1 0 (-1 ⬝ (⅟ D ⬝ C) ⬝ 1) 1 ⬝
+ (from_blocks (⅟ (A - B ⬝ ⅟ D ⬝ C)) (-⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ 0 ⬝ ⅟ D) 0 (⅟ D) ⬝
+ from_blocks 1 (-1 ⬝ (B ⬝ ⅟ D) ⬝ 1) 0 1)
+ -- combine into a single block matrix
+ simp only [from_blocks_multiply, invOf_one, Matrix.one_mul, Matrix.mul_one, Matrix.zero_mul,
+ Matrix.mul_zero, add_zero, zero_add, neg_zero, Matrix.mul_neg, Matrix.neg_mul, neg_neg, ←
+ Matrix.mul_assoc, add_comm]
+#align matrix.from_blocks₂₂_invertible Matrix.fromBlocks₂₂Invertible
+
+/-- A block matrix is invertible if the top left corner and the corresponding schur complement
+is. -/
+def fromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible A] [Invertible (D - C ⬝ ⅟ A ⬝ B)] :
+ Invertible (fromBlocks A B C D) :=
+ by
+ -- we argue by symmetry
+ letI := from_blocks₂₂_invertible D C B A
+ letI iDCBA :=
+ submatrix_equiv_invertible (from_blocks D C B A) (Equiv.sumComm _ _) (Equiv.sumComm _ _)
+ exact
+ iDCBA.copy' _
+ (from_blocks (⅟ A + ⅟ A ⬝ B ⬝ ⅟ (D - C ⬝ ⅟ A ⬝ B) ⬝ C ⬝ ⅟ A) (-⅟ A ⬝ B ⬝ ⅟ (D - C ⬝ ⅟ A ⬝ B))
+ (-⅟ (D - C ⬝ ⅟ A ⬝ B) ⬝ C ⬝ ⅟ A) (⅟ (D - C ⬝ ⅟ A ⬝ B)))
+ (from_blocks_submatrix_sum_swap_sum_swap _ _ _ _).symm
+ (from_blocks_submatrix_sum_swap_sum_swap _ _ _ _).symm
+#align matrix.from_blocks₁₁_invertible Matrix.fromBlocks₁₁Invertible
+
+theorem invOf_from_blocks₂₂_eq (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible D] [Invertible (A - B ⬝ ⅟ D ⬝ C)]
+ [Invertible (fromBlocks A B C D)] :
+ ⅟ (fromBlocks A B C D) =
+ fromBlocks (⅟ (A - B ⬝ ⅟ D ⬝ C)) (-⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ B ⬝ ⅟ D)
+ (-⅟ D ⬝ C ⬝ ⅟ (A - B ⬝ ⅟ D ⬝ C)) (⅟ D + ⅟ D ⬝ C ⬝ ⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ B ⬝ ⅟ D) :=
+ by
+ letI := from_blocks₂₂_invertible A B C D
+ convert (rfl : ⅟ (from_blocks A B C D) = _)
+#align matrix.inv_of_from_blocks₂₂_eq Matrix.invOf_from_blocks₂₂_eq
+
+theorem invOf_from_blocks₁₁_eq (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible A] [Invertible (D - C ⬝ ⅟ A ⬝ B)]
+ [Invertible (fromBlocks A B C D)] :
+ ⅟ (fromBlocks A B C D) =
+ fromBlocks (⅟ A + ⅟ A ⬝ B ⬝ ⅟ (D - C ⬝ ⅟ A ⬝ B) ⬝ C ⬝ ⅟ A) (-⅟ A ⬝ B ⬝ ⅟ (D - C ⬝ ⅟ A ⬝ B))
+ (-⅟ (D - C ⬝ ⅟ A ⬝ B) ⬝ C ⬝ ⅟ A) (⅟ (D - C ⬝ ⅟ A ⬝ B)) :=
+ by
+ letI := from_blocks₁₁_invertible A B C D
+ convert (rfl : ⅟ (from_blocks A B C D) = _)
+#align matrix.inv_of_from_blocks₁₁_eq Matrix.invOf_from_blocks₁₁_eq
+
+/-- If a block matrix is invertible and so is its bottom left element, then so is the corresponding
+Schur complement. -/
+def invertibleOfFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible D] [Invertible (fromBlocks A B C D)] :
+ Invertible (A - B ⬝ ⅟ D ⬝ C) :=
+ by
+ suffices Invertible (from_blocks (A - B ⬝ ⅟ D ⬝ C) 0 0 D) by
+ exact (invertible_of_from_blocks_zero₁₂_invertible (A - B ⬝ ⅟ D ⬝ C) 0 D).1
+ letI : Invertible (1 : Matrix n n α) := invertibleOne
+ letI : Invertible (1 : Matrix m m α) := invertibleOne
+ letI iDC : Invertible (from_blocks 1 0 (⅟ D ⬝ C) 1 : Matrix (Sum m n) (Sum m n) α) :=
+ from_blocks_zero₁₂_invertible _ _ _
+ letI iBD : Invertible (from_blocks 1 (B ⬝ ⅟ D) 0 1 : Matrix (Sum m n) (Sum m n) α) :=
+ from_blocks_zero₂₁_invertible _ _ _
+ letI iBDC := Invertible.copy ‹_› _ (from_blocks_eq_of_invertible₂₂ A B C D).symm
+ refine' (iBD.matrix_mul_left _).symm _
+ refine' (iDC.matrix_mul_right _).symm iBDC
+#align matrix.invertible_of_from_blocks₂₂_invertible Matrix.invertibleOfFromBlocks₂₂Invertible
+
+/-- If a block matrix is invertible and so is its bottom left element, then so is the corresponding
+Schur complement. -/
+def invertibleOfFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible A] [Invertible (fromBlocks A B C D)] :
+ Invertible (D - C ⬝ ⅟ A ⬝ B) :=
+ by
+ -- another symmetry argument
+ letI iABCD' :=
+ submatrix_equiv_invertible (from_blocks A B C D) (Equiv.sumComm _ _) (Equiv.sumComm _ _)
+ letI iDCBA := iABCD'.copy _ (from_blocks_submatrix_sum_swap_sum_swap _ _ _ _).symm
+ refine' invertible_of_from_blocks₂₂_invertible D C B A
+#align matrix.invertible_of_from_blocks₁₁_invertible Matrix.invertibleOfFromBlocks₁₁Invertible
+
+/-- `matrix.invertible_of_from_blocks₂₂_invertible` and `matrix.from_blocks₂₂_invertible` as an
+equivalence. -/
+def invertibleEquivFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible D] :
+ Invertible (fromBlocks A B C D) ≃ Invertible (A - B ⬝ ⅟ D ⬝ C)
+ where
+ toFun iABCD := invertible_of_from_blocks₂₂_invertible _ _ _ _
+ invFun i_schur := from_blocks₂₂_invertible _ _ _ _
+ left_inv iABCD := Subsingleton.elim _ _
+ right_inv i_schur := Subsingleton.elim _ _
+#align matrix.invertible_equiv_from_blocks₂₂_invertible Matrix.invertibleEquivFromBlocks₂₂Invertible
+
+/-- `matrix.invertible_of_from_blocks₁₁_invertible` and `matrix.from_blocks₁₁_invertible` as an
+equivalence. -/
+def invertibleEquivFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible A] :
+ Invertible (fromBlocks A B C D) ≃ Invertible (D - C ⬝ ⅟ A ⬝ B)
+ where
+ toFun iABCD := invertible_of_from_blocks₁₁_invertible _ _ _ _
+ invFun i_schur := from_blocks₁₁_invertible _ _ _ _
+ left_inv iABCD := Subsingleton.elim _ _
+ right_inv i_schur := Subsingleton.elim _ _
+#align matrix.invertible_equiv_from_blocks₁₁_invertible Matrix.invertibleEquivFromBlocks₁₁Invertible
+
+/-- If the bottom-left element of a block matrix is invertible, then the whole matrix is invertible
+iff the corresponding schur complement is. -/
+theorem isUnit_fromBlocks_iff_of_invertible₂₂ {A : Matrix m m α} {B : Matrix m n α}
+ {C : Matrix n m α} {D : Matrix n n α} [Invertible D] :
+ IsUnit (fromBlocks A B C D) ↔ IsUnit (A - B ⬝ ⅟ D ⬝ C) := by
+ simp only [← nonempty_invertible_iff_isUnit,
+ (invertible_equiv_from_blocks₂₂_invertible A B C D).nonempty_congr]
+#align matrix.is_unit_from_blocks_iff_of_invertible₂₂ Matrix.isUnit_fromBlocks_iff_of_invertible₂₂
+
+/-- If the top-right element of a block matrix is invertible, then the whole matrix is invertible
+iff the corresponding schur complement is. -/
+theorem isUnit_fromBlocks_iff_of_invertible₁₁ {A : Matrix m m α} {B : Matrix m n α}
+ {C : Matrix n m α} {D : Matrix n n α} [Invertible A] :
+ IsUnit (fromBlocks A B C D) ↔ IsUnit (D - C ⬝ ⅟ A ⬝ B) := by
+ simp only [← nonempty_invertible_iff_isUnit,
+ (invertible_equiv_from_blocks₁₁_invertible A B C D).nonempty_congr]
+#align matrix.is_unit_from_blocks_iff_of_invertible₁₁ Matrix.isUnit_fromBlocks_iff_of_invertible₁₁
+
+end Block
+
/-! ### Lemmas about `matrix.det` -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/2a0ce625dbb0ffbc7d1316597de0b25c1ec75303
@@ -270,7 +270,7 @@ theorem det_from_blocks₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matri
have :
from_blocks A B C D = (from_blocks D C B A).submatrix (Equiv.sumComm _ _) (Equiv.sumComm _ _) :=
by
- ext (i j)
+ ext i j
cases i <;> cases j <;> rfl
rw [this, det_submatrix_equiv_self, det_from_blocks₁₁]
#align matrix.det_from_blocks₂₂ Matrix.det_from_blocks₂₂
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -324,7 +324,6 @@ open scoped Matrix
variable {𝕜 : Type _} [IsROrC 𝕜]
--- mathport name: «expr ⊕ᵥ »
scoped infixl:65 " ⊕ᵥ " => Sum.elim
theorem schur_complement_eq₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A : Matrix m m 𝕜}
mathlib commit https://github.com/leanprover-community/mathlib/commit/a3e83f0fa4391c8740f7d773a7a9b74e311ae2a3
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Alexander Bentkamp, Eric Wieser, Jeremy Avigad, Johan Commelin
! This file was ported from Lean 3 source module linear_algebra.matrix.schur_complement
-! leanprover-community/mathlib commit a07a7ae98384cd6485d7825e161e528ba78ef3bc
+! leanprover-community/mathlib commit 96aa788f3e443efb3dace8a634258a9259364f43
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -20,6 +20,10 @@ This file proves properties of 2×2 block matrices `[A B; C D]` that relate to t
* `matrix.det_from_blocks₁₁`, `matrix.det_from_blocks₂₂`: determinant of a block matrix in terms of
the Schur complement.
+ * `matrix.inv_of_from_blocks_zero₂₁_eq`, `matrix.inv_of_from_blocks_zero₁₂_eq`: the inverse of a
+ block triangular matrix.
+ * `matrix.is_unit_from_blocks_zero₂₁`, `matrix.is_unit_from_blocks_zero₁₂`: invertibility of a
+ block triangular matrix.
* `matrix.det_one_add_mul_comm`: the **Weinstein–Aronszajn identity**.
* `matrix.schur_complement_pos_semidef_iff` : If a matrix `A` is positive definite, then
`[A B; Bᴴ D]` is postive semidefinite if and only if `D - Bᴴ A⁻¹ B` is postive semidefinite.
@@ -67,6 +71,174 @@ theorem fromBlocks_eq_of_invertible₂₂ (A : Matrix l m α) (B : Matrix l n α
from_blocks_submatrix_sum_swap_sum_swap] using from_blocks_eq_of_invertible₁₁ D C B A
#align matrix.from_blocks_eq_of_invertible₂₂ Matrix.fromBlocks_eq_of_invertible₂₂
+section Triangular
+
+/-! #### Block triangular matrices -/
+
+
+/-- An upper-block-triangular matrix is invertible if its diagonal is. -/
+def fromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
+ [Invertible A] [Invertible D] : Invertible (fromBlocks A B 0 D) :=
+ invertibleOfLeftInverse _ (fromBlocks (⅟ A) (-⅟ A ⬝ B ⬝ ⅟ D) 0 (⅟ D)) <| by
+ simp_rw [from_blocks_multiply, Matrix.mul_zero, Matrix.zero_mul, zero_add, add_zero,
+ Matrix.neg_mul, Matrix.invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_right_neg,
+ from_blocks_one]
+#align matrix.from_blocks_zero₂₁_invertible Matrix.fromBlocksZero₂₁Invertible
+
+/-- A lower-block-triangular matrix is invertible if its diagonal is. -/
+def fromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
+ [Invertible A] [Invertible D] : Invertible (fromBlocks A 0 C D) :=
+ invertibleOfLeftInverse _
+ (fromBlocks (⅟ A) 0 (-⅟ D ⬝ C ⬝ ⅟ A)
+ (⅟ D)) <|-- a symmetry argument is more work than just copying the proof
+ by
+ simp_rw [from_blocks_multiply, Matrix.mul_zero, Matrix.zero_mul, zero_add, add_zero,
+ Matrix.neg_mul, Matrix.invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_left_neg,
+ from_blocks_one]
+#align matrix.from_blocks_zero₁₂_invertible Matrix.fromBlocksZero₁₂Invertible
+
+theorem invOf_fromBlocks_zero₂₁_eq (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
+ [Invertible A] [Invertible D] [Invertible (fromBlocks A B 0 D)] :
+ ⅟ (fromBlocks A B 0 D) = fromBlocks (⅟ A) (-⅟ A ⬝ B ⬝ ⅟ D) 0 (⅟ D) :=
+ by
+ letI := from_blocks_zero₂₁_invertible A B D
+ convert (rfl : ⅟ (from_blocks A B 0 D) = _)
+#align matrix.inv_of_from_blocks_zero₂₁_eq Matrix.invOf_fromBlocks_zero₂₁_eq
+
+theorem invOf_fromBlocks_zero₁₂_eq (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
+ [Invertible A] [Invertible D] [Invertible (fromBlocks A 0 C D)] :
+ ⅟ (fromBlocks A 0 C D) = fromBlocks (⅟ A) 0 (-⅟ D ⬝ C ⬝ ⅟ A) (⅟ D) :=
+ by
+ letI := from_blocks_zero₁₂_invertible A C D
+ convert (rfl : ⅟ (from_blocks A 0 C D) = _)
+#align matrix.inv_of_from_blocks_zero₁₂_eq Matrix.invOf_fromBlocks_zero₁₂_eq
+
+/-- Both diagonal entries of an invertible upper-block-triangular matrix are invertible (by reading
+off the diagonal entries of the inverse). -/
+def invertibleOfFromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
+ [Invertible (fromBlocks A B 0 D)] : Invertible A × Invertible D
+ where
+ fst :=
+ invertibleOfLeftInverse _ (⅟ (fromBlocks A B 0 D)).toBlocks₁₁ <|
+ by
+ have := Matrix.invOf_mul_self (from_blocks A B 0 D)
+ rw [← from_blocks_to_blocks (⅟ (from_blocks A B 0 D)), from_blocks_multiply] at this
+ replace := congr_arg Matrix.toBlocks₁₁ this
+ simpa only [Matrix.toBlocks_fromBlocks₁₁, Matrix.mul_zero, add_zero, ← from_blocks_one] using
+ this
+ snd :=
+ invertibleOfRightInverse _ (⅟ (fromBlocks A B 0 D)).toBlocks₂₂ <|
+ by
+ have := Matrix.mul_invOf_self (from_blocks A B 0 D)
+ rw [← from_blocks_to_blocks (⅟ (from_blocks A B 0 D)), from_blocks_multiply] at this
+ replace := congr_arg Matrix.toBlocks₂₂ this
+ simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.zero_mul, zero_add, ← from_blocks_one] using
+ this
+#align matrix.invertible_of_from_blocks_zero₂₁_invertible Matrix.invertibleOfFromBlocksZero₂₁Invertible
+
+/-- Both diagonal entries of an invertible lower-block-triangular matrix are invertible (by reading
+off the diagonal entries of the inverse). -/
+def invertibleOfFromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
+ [Invertible (fromBlocks A 0 C D)] : Invertible A × Invertible D
+ where
+ fst :=
+ invertibleOfRightInverse _ (⅟ (fromBlocks A 0 C D)).toBlocks₁₁ <|
+ by
+ have := Matrix.mul_invOf_self (from_blocks A 0 C D)
+ rw [← from_blocks_to_blocks (⅟ (from_blocks A 0 C D)), from_blocks_multiply] at this
+ replace := congr_arg Matrix.toBlocks₁₁ this
+ simpa only [Matrix.toBlocks_fromBlocks₁₁, Matrix.zero_mul, add_zero, ← from_blocks_one] using
+ this
+ snd :=
+ invertibleOfLeftInverse _ (⅟ (fromBlocks A 0 C D)).toBlocks₂₂ <|
+ by
+ have := Matrix.invOf_mul_self (from_blocks A 0 C D)
+ rw [← from_blocks_to_blocks (⅟ (from_blocks A 0 C D)), from_blocks_multiply] at this
+ replace := congr_arg Matrix.toBlocks₂₂ this
+ simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.mul_zero, zero_add, ← from_blocks_one] using
+ this
+#align matrix.invertible_of_from_blocks_zero₁₂_invertible Matrix.invertibleOfFromBlocksZero₁₂Invertible
+
+/-- `invertible_of_from_blocks_zero₂₁_invertible` and `from_blocks_zero₂₁_invertible` form
+an equivalence. -/
+def fromBlocksZero₂₁InvertibleEquiv (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α) :
+ Invertible (fromBlocks A B 0 D) ≃ Invertible A × Invertible D
+ where
+ toFun _ := invertible_of_from_blocks_zero₂₁_invertible A B D
+ invFun i := by letI := i.1 <;> letI := i.2 <;> exact from_blocks_zero₂₁_invertible A B D
+ left_inv _ := Subsingleton.elim _ _
+ right_inv _ := Subsingleton.elim _ _
+#align matrix.from_blocks_zero₂₁_invertible_equiv Matrix.fromBlocksZero₂₁InvertibleEquiv
+
+/-- `invertible_of_from_blocks_zero₁₂_invertible` and `from_blocks_zero₁₂_invertible` form
+an equivalence. -/
+def fromBlocksZero₁₂InvertibleEquiv (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α) :
+ Invertible (fromBlocks A 0 C D) ≃ Invertible A × Invertible D
+ where
+ toFun _ := invertible_of_from_blocks_zero₁₂_invertible A C D
+ invFun i := by letI := i.1 <;> letI := i.2 <;> exact from_blocks_zero₁₂_invertible A C D
+ left_inv _ := Subsingleton.elim _ _
+ right_inv _ := Subsingleton.elim _ _
+#align matrix.from_blocks_zero₁₂_invertible_equiv Matrix.fromBlocksZero₁₂InvertibleEquiv
+
+/-- An upper block-triangular matrix is invertible iff both elements of its diagonal are.
+
+This is a propositional form of `matrix.from_blocks_zero₂₁_invertible_equiv`. -/
+@[simp]
+theorem isUnit_fromBlocks_zero₂₁ {A : Matrix m m α} {B : Matrix m n α} {D : Matrix n n α} :
+ IsUnit (fromBlocks A B 0 D) ↔ IsUnit A ∧ IsUnit D := by
+ simp only [← nonempty_invertible_iff_isUnit, ← nonempty_prod,
+ (from_blocks_zero₂₁_invertible_equiv _ _ _).nonempty_congr]
+#align matrix.is_unit_from_blocks_zero₂₁ Matrix.isUnit_fromBlocks_zero₂₁
+
+/-- A lower block-triangular matrix is invertible iff both elements of its diagonal are.
+
+This is a propositional form of `matrix.from_blocks_zero₁₂_invertible_equiv` forms an `iff`. -/
+@[simp]
+theorem isUnit_fromBlocks_zero₁₂ {A : Matrix m m α} {C : Matrix n m α} {D : Matrix n n α} :
+ IsUnit (fromBlocks A 0 C D) ↔ IsUnit A ∧ IsUnit D := by
+ simp only [← nonempty_invertible_iff_isUnit, ← nonempty_prod,
+ (from_blocks_zero₁₂_invertible_equiv _ _ _).nonempty_congr]
+#align matrix.is_unit_from_blocks_zero₁₂ Matrix.isUnit_fromBlocks_zero₁₂
+
+/-- An expression for the inverse of an upper block-triangular matrix, when either both elements of
+diagonal are invertible, or both are not. -/
+theorem inv_fromBlocks_zero₂₁_of_isUnit_iff (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
+ (hAD : IsUnit A ↔ IsUnit D) : (fromBlocks A B 0 D)⁻¹ = fromBlocks A⁻¹ (-A⁻¹ ⬝ B ⬝ D⁻¹) 0 D⁻¹ :=
+ by
+ by_cases hA : IsUnit A
+ · have hD := hAD.mp hA
+ cases hA.nonempty_invertible
+ cases hD.nonempty_invertible
+ letI := from_blocks_zero₂₁_invertible A B D
+ simp_rw [← inv_of_eq_nonsing_inv, inv_of_from_blocks_zero₂₁_eq]
+ · have hD := hAD.not.mp hA
+ have : ¬IsUnit (from_blocks A B 0 D) :=
+ is_unit_from_blocks_zero₂₁.not.mpr (not_and'.mpr fun _ => hA)
+ simp_rw [nonsing_inv_eq_ring_inverse, Ring.inverse_non_unit _ hA, Ring.inverse_non_unit _ hD,
+ Ring.inverse_non_unit _ this, Matrix.zero_mul, neg_zero, from_blocks_zero]
+#align matrix.inv_from_blocks_zero₂₁_of_is_unit_iff Matrix.inv_fromBlocks_zero₂₁_of_isUnit_iff
+
+/-- An expression for the inverse of a lower block-triangular matrix, when either both elements of
+diagonal are invertible, or both are not. -/
+theorem inv_fromBlocks_zero₁₂_of_isUnit_iff (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
+ (hAD : IsUnit A ↔ IsUnit D) : (fromBlocks A 0 C D)⁻¹ = fromBlocks A⁻¹ 0 (-D⁻¹ ⬝ C ⬝ A⁻¹) D⁻¹ :=
+ by
+ by_cases hA : IsUnit A
+ · have hD := hAD.mp hA
+ cases hA.nonempty_invertible
+ cases hD.nonempty_invertible
+ letI := from_blocks_zero₁₂_invertible A C D
+ simp_rw [← inv_of_eq_nonsing_inv, inv_of_from_blocks_zero₁₂_eq]
+ · have hD := hAD.not.mp hA
+ have : ¬IsUnit (from_blocks A 0 C D) :=
+ is_unit_from_blocks_zero₁₂.not.mpr (not_and'.mpr fun _ => hA)
+ simp_rw [nonsing_inv_eq_ring_inverse, Ring.inverse_non_unit _ hA, Ring.inverse_non_unit _ hD,
+ Ring.inverse_non_unit _ this, Matrix.zero_mul, neg_zero, from_blocks_zero]
+#align matrix.inv_from_blocks_zero₁₂_of_is_unit_iff Matrix.inv_fromBlocks_zero₁₂_of_isUnit_iff
+
+end Triangular
+
/-! ### Lemmas about `matrix.det` -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/7e5137f579de09a059a5ce98f364a04e221aabf0
@@ -119,7 +119,6 @@ theorem det_one_add_mul_comm (A : Matrix m n α) (B : Matrix n m α) :
det (1 + A ⬝ B) = det (fromBlocks 1 (-A) B 1) := by
rw [det_from_blocks_one₂₂, Matrix.neg_mul, sub_neg_eq_add]
_ = det (1 + B ⬝ A) := by rw [det_from_blocks_one₁₁, Matrix.mul_neg, sub_neg_eq_add]
-
#align matrix.det_one_add_mul_comm Matrix.det_one_add_mul_comm
/-- Alternate statement of the **Weinstein–Aronszajn identity** -/
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -218,7 +218,7 @@ theorem PosSemidef.from_blocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A
· refine' fun h => ⟨h.1, fun x => _⟩
have := h.2 (-(A⁻¹ ⬝ B).mulVec x ⊕ᵥ x)
rw [dot_product_mul_vec, schur_complement_eq₁₁ B D _ _ hA.1, neg_add_self, dot_product_zero,
- zero_add] at this
+ zero_add] at this
rw [dot_product_mul_vec]; exact this
· refine' fun h => ⟨h.1, fun x => _⟩
rw [dot_product_mul_vec, ← Sum.elim_comp_inl_inr x, schur_complement_eq₁₁ B D _ _ hA.1, map_add]
@@ -234,7 +234,10 @@ theorem PosSemidef.from_blocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A
by
rw [← pos_semidef_submatrix_equiv (Equiv.sumComm n m), Equiv.sumComm_apply,
from_blocks_submatrix_sum_swap_sum_swap]
- convert pos_semidef.from_blocks₁₁ _ _ hD <;> first |infer_instance|simp
+ convert pos_semidef.from_blocks₁₁ _ _ hD <;>
+ first
+ | infer_instance
+ | simp
#align matrix.pos_semidef.from_blocks₂₂ Matrix.PosSemidef.from_blocks₂₂
end IsROrC
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -31,7 +31,7 @@ variable {l m n α : Type _}
namespace Matrix
-open Matrix
+open scoped Matrix
section CommRing
@@ -149,7 +149,7 @@ end CommRing
section IsROrC
-open Matrix
+open scoped Matrix
variable {𝕜 : Type _} [IsROrC 𝕜]
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -219,15 +219,13 @@ theorem PosSemidef.from_blocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A
have := h.2 (-(A⁻¹ ⬝ B).mulVec x ⊕ᵥ x)
rw [dot_product_mul_vec, schur_complement_eq₁₁ B D _ _ hA.1, neg_add_self, dot_product_zero,
zero_add] at this
- rw [dot_product_mul_vec]
- exact this
+ rw [dot_product_mul_vec]; exact this
· refine' fun h => ⟨h.1, fun x => _⟩
rw [dot_product_mul_vec, ← Sum.elim_comp_inl_inr x, schur_complement_eq₁₁ B D _ _ hA.1, map_add]
apply le_add_of_nonneg_of_le
· rw [← dot_product_mul_vec]
apply hA.pos_semidef.2
- · rw [← dot_product_mul_vec]
- apply h.2
+ · rw [← dot_product_mul_vec]; apply h.2
#align matrix.pos_semidef.from_blocks₁₁ Matrix.PosSemidef.from_blocks₁₁
theorem PosSemidef.from_blocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : Matrix m m 𝕜)
mathlib commit https://github.com/leanprover-community/mathlib/commit/2651125b48fc5c170ab1111afd0817c903b1fc6c
@@ -1,37 +1,157 @@
/-
Copyright (c) 2022 Alexander Bentkamp. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
-Authors: Alexander Bentkamp, Jeremy Avigad, Johan Commelin
+Authors: Alexander Bentkamp, Eric Wieser, Jeremy Avigad, Johan Commelin
! This file was ported from Lean 3 source module linear_algebra.matrix.schur_complement
-! leanprover-community/mathlib commit 70fd9563a21e7b963887c9360bd29b2393e6225a
+! leanprover-community/mathlib commit a07a7ae98384cd6485d7825e161e528ba78ef3bc
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.LinearAlgebra.Matrix.NonsingularInverse
import Mathbin.LinearAlgebra.Matrix.PosDef
-/-! # Schur complement
+/-! # 2×2 block matrices and the Schur complement
-This file proves properties of the Schur complement `D - C A⁻¹ B` of a block matrix `[A B; C D]`.
+This file proves properties of 2×2 block matrices `[A B; C D]` that relate to the Schur complement
+`D - C⬝A⁻¹⬝B`.
-The determinant of a block matrix in terms of the Schur complement is expressed in the lemmas
-`matrix.det_from_blocks₁₁` and `matrix.det_from_blocks₂₂` in the file
-`linear_algebra.matrix.nonsingular_inverse`.
+## Main results
-## Main result
-
- * `matrix.schur_complement_pos_semidef_iff` : If a matrix `A` is positive definite, then `[A B; Bᴴ
- D]` is postive semidefinite if and only if `D - Bᴴ A⁻¹ B` is postive semidefinite.
+ * `matrix.det_from_blocks₁₁`, `matrix.det_from_blocks₂₂`: determinant of a block matrix in terms of
+ the Schur complement.
+ * `matrix.det_one_add_mul_comm`: the **Weinstein–Aronszajn identity**.
+ * `matrix.schur_complement_pos_semidef_iff` : If a matrix `A` is positive definite, then
+ `[A B; Bᴴ D]` is postive semidefinite if and only if `D - Bᴴ A⁻¹ B` is postive semidefinite.
-/
+variable {l m n α : Type _}
+
namespace Matrix
open Matrix
-variable {n : Type _} {m : Type _} {𝕜 : Type _} [IsROrC 𝕜]
+section CommRing
+
+variable [Fintype l] [Fintype m] [Fintype n]
+
+variable [DecidableEq l] [DecidableEq m] [DecidableEq n]
+
+variable [CommRing α]
+
+/-- LDU decomposition of a block matrix with an invertible top-left corner, using the
+Schur complement. -/
+theorem fromBlocks_eq_of_invertible₁₁ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix l m α)
+ (D : Matrix l n α) [Invertible A] :
+ fromBlocks A B C D =
+ fromBlocks 1 0 (C ⬝ ⅟ A) 1 ⬝ fromBlocks A 0 0 (D - C ⬝ ⅟ A ⬝ B) ⬝
+ fromBlocks 1 (⅟ A ⬝ B) 0 1 :=
+ by
+ simp only [from_blocks_multiply, Matrix.mul_zero, Matrix.zero_mul, add_zero, zero_add,
+ Matrix.one_mul, Matrix.mul_one, Matrix.invOf_mul_self, Matrix.mul_invOf_self_assoc,
+ Matrix.mul_invOf_mul_self_cancel, Matrix.mul_assoc, add_sub_cancel'_right]
+#align matrix.from_blocks_eq_of_invertible₁₁ Matrix.fromBlocks_eq_of_invertible₁₁
+
+/-- LDU decomposition of a block matrix with an invertible bottom-right corner, using the
+Schur complement. -/
+theorem fromBlocks_eq_of_invertible₂₂ (A : Matrix l m α) (B : Matrix l n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible D] :
+ fromBlocks A B C D =
+ fromBlocks 1 (B ⬝ ⅟ D) 0 1 ⬝ fromBlocks (A - B ⬝ ⅟ D ⬝ C) 0 0 D ⬝
+ fromBlocks 1 0 (⅟ D ⬝ C) 1 :=
+ (Matrix.reindex (Equiv.sumComm _ _) (Equiv.sumComm _ _)).Injective <| by
+ simpa [reindex_apply, Equiv.sumComm_symm, ← submatrix_mul_equiv _ _ _ (Equiv.sumComm n m), ←
+ submatrix_mul_equiv _ _ _ (Equiv.sumComm n l), Equiv.sumComm_apply,
+ from_blocks_submatrix_sum_swap_sum_swap] using from_blocks_eq_of_invertible₁₁ D C B A
+#align matrix.from_blocks_eq_of_invertible₂₂ Matrix.fromBlocks_eq_of_invertible₂₂
+
+/-! ### Lemmas about `matrix.det` -/
+
+
+section Det
+
+/-- Determinant of a 2×2 block matrix, expanded around an invertible top left element in terms of
+the Schur complement. -/
+theorem det_from_blocks₁₁ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible A] :
+ (Matrix.fromBlocks A B C D).det = det A * det (D - C ⬝ ⅟ A ⬝ B) := by
+ rw [from_blocks_eq_of_invertible₁₁, det_mul, det_mul, det_from_blocks_zero₂₁,
+ det_from_blocks_zero₂₁, det_from_blocks_zero₁₂, det_one, det_one, one_mul, one_mul, mul_one]
+#align matrix.det_from_blocks₁₁ Matrix.det_from_blocks₁₁
+
+@[simp]
+theorem det_fromBlocks_one₁₁ (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α) :
+ (Matrix.fromBlocks 1 B C D).det = det (D - C ⬝ B) :=
+ by
+ haveI : Invertible (1 : Matrix m m α) := invertibleOne
+ rw [det_from_blocks₁₁, invOf_one, Matrix.mul_one, det_one, one_mul]
+#align matrix.det_from_blocks_one₁₁ Matrix.det_fromBlocks_one₁₁
+
+/-- Determinant of a 2×2 block matrix, expanded around an invertible bottom right element in terms
+of the Schur complement. -/
+theorem det_from_blocks₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
+ (D : Matrix n n α) [Invertible D] :
+ (Matrix.fromBlocks A B C D).det = det D * det (A - B ⬝ ⅟ D ⬝ C) :=
+ by
+ have :
+ from_blocks A B C D = (from_blocks D C B A).submatrix (Equiv.sumComm _ _) (Equiv.sumComm _ _) :=
+ by
+ ext (i j)
+ cases i <;> cases j <;> rfl
+ rw [this, det_submatrix_equiv_self, det_from_blocks₁₁]
+#align matrix.det_from_blocks₂₂ Matrix.det_from_blocks₂₂
+
+@[simp]
+theorem det_fromBlocks_one₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) :
+ (Matrix.fromBlocks A B C 1).det = det (A - B ⬝ C) :=
+ by
+ haveI : Invertible (1 : Matrix n n α) := invertibleOne
+ rw [det_from_blocks₂₂, invOf_one, Matrix.mul_one, det_one, one_mul]
+#align matrix.det_from_blocks_one₂₂ Matrix.det_fromBlocks_one₂₂
+
+/-- The **Weinstein–Aronszajn identity**. Note the `1` on the LHS is of shape m×m, while the `1` on
+the RHS is of shape n×n. -/
+theorem det_one_add_mul_comm (A : Matrix m n α) (B : Matrix n m α) :
+ det (1 + A ⬝ B) = det (1 + B ⬝ A) :=
+ calc
+ det (1 + A ⬝ B) = det (fromBlocks 1 (-A) B 1) := by
+ rw [det_from_blocks_one₂₂, Matrix.neg_mul, sub_neg_eq_add]
+ _ = det (1 + B ⬝ A) := by rw [det_from_blocks_one₁₁, Matrix.mul_neg, sub_neg_eq_add]
+
+#align matrix.det_one_add_mul_comm Matrix.det_one_add_mul_comm
+
+/-- Alternate statement of the **Weinstein–Aronszajn identity** -/
+theorem det_mul_add_one_comm (A : Matrix m n α) (B : Matrix n m α) :
+ det (A ⬝ B + 1) = det (B ⬝ A + 1) := by rw [add_comm, det_one_add_mul_comm, add_comm]
+#align matrix.det_mul_add_one_comm Matrix.det_mul_add_one_comm
+
+theorem det_one_sub_mul_comm (A : Matrix m n α) (B : Matrix n m α) :
+ det (1 - A ⬝ B) = det (1 - B ⬝ A) := by
+ rw [sub_eq_add_neg, ← Matrix.neg_mul, det_one_add_mul_comm, Matrix.mul_neg, ← sub_eq_add_neg]
+#align matrix.det_one_sub_mul_comm Matrix.det_one_sub_mul_comm
+
+/-- A special case of the **Matrix determinant lemma** for when `A = I`.
+
+TODO: show this more generally. -/
+theorem det_one_add_col_mul_row (u v : m → α) : det (1 + col u ⬝ row v) = 1 + v ⬝ᵥ u := by
+ rw [det_one_add_mul_comm, det_unique, Pi.add_apply, Pi.add_apply, Matrix.one_apply_eq,
+ Matrix.row_mul_col_apply]
+#align matrix.det_one_add_col_mul_row Matrix.det_one_add_col_mul_row
+
+end Det
+
+end CommRing
+
+/-! ### Lemmas about `ℝ` and `ℂ`-/
+
+
+section IsROrC
+
+open Matrix
+
+variable {𝕜 : Type _} [IsROrC 𝕜]
-- mathport name: «expr ⊕ᵥ »
scoped infixl:65 " ⊕ᵥ " => Sum.elim
@@ -62,14 +182,6 @@ theorem schur_complement_eq₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : M
abel
#align matrix.schur_complement_eq₂₂ Matrix.schur_complement_eq₂₂
-end Matrix
-
-namespace Matrix
-
-open Matrix
-
-variable {n : Type _} {m : Type _} {𝕜 : Type _} [IsROrC 𝕜]
-
theorem IsHermitian.from_blocks₁₁ [Fintype m] [DecidableEq m] {A : Matrix m m 𝕜} (B : Matrix m n 𝕜)
(D : Matrix n n 𝕜) (hA : A.IsHermitian) :
(fromBlocks A B Bᴴ D).IsHermitian ↔ (D - Bᴴ ⬝ A⁻¹ ⬝ B).IsHermitian :=
@@ -127,5 +239,7 @@ theorem PosSemidef.from_blocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A
convert pos_semidef.from_blocks₁₁ _ _ hD <;> first |infer_instance|simp
#align matrix.pos_semidef.from_blocks₂₂ Matrix.PosSemidef.from_blocks₂₂
+end IsROrC
+
end Matrix
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
StarOrderedRing
a mixin (#11872)
This makes StarOrderedRing
take StarRing
as a parameter instead of extending it, and as a result moves the typeclass to Prop
. It was already a mixin with respect to the order and algebraic structure. There are two primary motivations:
C(α, R)
is a StarOrderedRing
with [StarOrderedRing C(α, R)]
, as currently there is no typeclass on R
which would naturally guarantee this property. This is relevant as we want this type class on continuous functions for the continuous functional calculus.StarOrderedRing
instance on C(α, A)
where A
is a complex (or even real) C⋆-algebra, and making this a mixin avoids loops with StarRing
.@@ -477,7 +477,7 @@ end CommRing
section StarOrderedRing
-variable {𝕜 : Type*} [CommRing 𝕜] [PartialOrder 𝕜] [StarOrderedRing 𝕜]
+variable {𝕜 : Type*} [CommRing 𝕜] [PartialOrder 𝕜] [StarRing 𝕜] [StarOrderedRing 𝕜]
scoped infixl:65 " ⊕ᵥ " => Sum.elim
mul
-div
cancellation lemmas (#11530)
Lemma names around cancellation of multiplication and division are a mess.
This PR renames a handful of them according to the following table (each big row contains the multiplicative statement, then the three rows contain the GroupWithZero
lemma name, the Group
lemma, the AddGroup
lemma name).
| Statement | New name | Old name | |
@@ -56,7 +56,7 @@ theorem fromBlocks_eq_of_invertible₁₁ (A : Matrix m m α) (B : Matrix m n α
fromBlocks 1 (⅟ A * B) 0 1 := by
simp only [fromBlocks_multiply, Matrix.mul_zero, Matrix.zero_mul, add_zero, zero_add,
Matrix.one_mul, Matrix.mul_one, invOf_mul_self, Matrix.mul_invOf_self_assoc,
- Matrix.mul_invOf_mul_self_cancel, Matrix.mul_assoc, add_sub_cancel'_right]
+ Matrix.mul_invOf_mul_self_cancel, Matrix.mul_assoc, add_sub_cancel]
#align matrix.from_blocks_eq_of_invertible₁₁ Matrix.fromBlocks_eq_of_invertible₁₁
/-- LDU decomposition of a block matrix with an invertible bottom-right corner, using the
Empty lines were removed by executing the following Python script twice
import os
import re
# Loop through each file in the repository
for dir_path, dirs, files in os.walk('.'):
for filename in files:
if filename.endswith('.lean'):
file_path = os.path.join(dir_path, filename)
# Open the file and read its contents
with open(file_path, 'r') as file:
content = file.read()
# Use a regular expression to replace sequences of "variable" lines separated by empty lines
# with sequences without empty lines
modified_content = re.sub(r'(variable.*\n)\n(variable(?! .* in))', r'\1\2', content)
# Write the modified content back to the file
with open(file_path, 'w') as file:
file.write(modified_content)
@@ -44,9 +44,7 @@ open scoped Matrix
section CommRing
variable [Fintype l] [Fintype m] [Fintype n]
-
variable [DecidableEq l] [DecidableEq m] [DecidableEq n]
-
variable [CommRing α]
/-- LDU decomposition of a block matrix with an invertible top-left corner, using the
@@ -556,9 +556,7 @@ theorem PosSemidef.fromBlocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A :
rw [← posSemidef_submatrix_equiv (Equiv.sumComm n m), Equiv.sumComm_apply,
fromBlocks_submatrix_sum_swap_sum_swap]
convert PosSemidef.fromBlocks₁₁ Bᴴ A hD <;>
- first
- | infer_instance
- | simp
+ simp
#align matrix.pos_semidef.from_blocks₂₂ Matrix.PosSemidef.fromBlocks₂₂
end StarOrderedRing
refine
s (#10762)
I replaced a few "terminal" refine/refine'
s with exact
.
The strategy was very simple-minded: essentially any refine
whose following line had smaller indentation got replaced by exact
and then I cleaned up the mess.
This PR certainly leaves some further terminal refine
s, but maybe the current change is beneficial.
@@ -327,7 +327,7 @@ def invertibleOfFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n
fromBlocksZero₂₁Invertible _ _ _
letI iBDC := Invertible.copy ‹_› _ (fromBlocks_eq_of_invertible₂₂ A B C D).symm
refine' (iBD.mulLeft _).symm _
- refine' (iDC.mulRight _).symm iBDC
+ exact (iDC.mulRight _).symm iBDC
#align matrix.invertible_of_from_blocks₂₂_invertible Matrix.invertibleOfFromBlocks₂₂Invertible
/-- If a block matrix is invertible and so is its bottom left element, then so is the corresponding
@@ -339,7 +339,7 @@ def invertibleOfFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n
letI iABCD' :=
submatrixEquivInvertible (fromBlocks A B C D) (Equiv.sumComm _ _) (Equiv.sumComm _ _)
letI iDCBA := iABCD'.copy _ (fromBlocks_submatrix_sum_swap_sum_swap _ _ _ _).symm
- refine' invertibleOfFromBlocks₂₂Invertible D C B A
+ exact invertibleOfFromBlocks₂₂Invertible D C B A
#align matrix.invertible_of_from_blocks₁₁_invertible Matrix.invertibleOfFromBlocks₁₁Invertible
/-- `Matrix.invertibleOfFromBlocks₂₂Invertible` and `Matrix.fromBlocks₂₂Invertible` as an
Matrix.mulVec
and Matrix.vecMul
get infix notation (#10297)
Zulip discussion: https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/Notation.20for.20mul_vec.20and.20vec_mul
Co-authored-by: Martin Dvorak <mdvorak@ista.ac.at>
@@ -453,7 +453,7 @@ theorem det_one_add_col_mul_row (u v : m → α) : det (1 + col u * row v) = 1 +
/-- The **Matrix determinant lemma**
TODO: show the more general version without `hA : IsUnit A.det` as
-`(A + col u * row v).det = A.det + v ⬝ᵥ (adjugate A).mulVec u`.
+`(A + col u * row v).det = A.det + v ⬝ᵥ (adjugate A) *ᵥ u`.
-/
theorem det_add_col_mul_row {A : Matrix m m α} (hA : IsUnit A.det) (u v : m → α) :
(A + col u * row v).det = A.det * (1 + row v * A⁻¹ * col u).det := by
@@ -486,9 +486,9 @@ scoped infixl:65 " ⊕ᵥ " => Sum.elim
theorem schur_complement_eq₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A : Matrix m m 𝕜}
(B : Matrix m n 𝕜) (D : Matrix n n 𝕜) (x : m → 𝕜) (y : n → 𝕜) [Invertible A]
(hA : A.IsHermitian) :
- vecMul (star (x ⊕ᵥ y)) (fromBlocks A B Bᴴ D) ⬝ᵥ (x ⊕ᵥ y) =
- vecMul (star (x + (A⁻¹ * B).mulVec y)) A ⬝ᵥ (x + (A⁻¹ * B).mulVec y) +
- vecMul (star y) (D - Bᴴ * A⁻¹ * B) ⬝ᵥ y := by
+ (star (x ⊕ᵥ y)) ᵥ* (fromBlocks A B Bᴴ D) ⬝ᵥ (x ⊕ᵥ y) =
+ (star (x + (A⁻¹ * B) *ᵥ y)) ᵥ* A ⬝ᵥ (x + (A⁻¹ * B) *ᵥ y) +
+ (star y) ᵥ* (D - Bᴴ * A⁻¹ * B) ⬝ᵥ y := by
simp [Function.star_sum_elim, fromBlocks_mulVec, vecMul_fromBlocks, add_vecMul,
dotProduct_mulVec, vecMul_sub, Matrix.mul_assoc, vecMul_mulVec, hA.eq,
conjTranspose_nonsing_inv, star_mulVec]
@@ -498,9 +498,9 @@ theorem schur_complement_eq₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A : M
theorem schur_complement_eq₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : Matrix m m 𝕜)
(B : Matrix m n 𝕜) {D : Matrix n n 𝕜} (x : m → 𝕜) (y : n → 𝕜) [Invertible D]
(hD : D.IsHermitian) :
- vecMul (star (x ⊕ᵥ y)) (fromBlocks A B Bᴴ D) ⬝ᵥ (x ⊕ᵥ y) =
- vecMul (star ((D⁻¹ * Bᴴ).mulVec x + y)) D ⬝ᵥ ((D⁻¹ * Bᴴ).mulVec x + y) +
- vecMul (star x) (A - B * D⁻¹ * Bᴴ) ⬝ᵥ x := by
+ (star (x ⊕ᵥ y)) ᵥ* (fromBlocks A B Bᴴ D) ⬝ᵥ (x ⊕ᵥ y) =
+ (star ((D⁻¹ * Bᴴ) *ᵥ x + y)) ᵥ* D ⬝ᵥ ((D⁻¹ * Bᴴ) *ᵥ x + y) +
+ (star x) ᵥ* (A - B * D⁻¹ * Bᴴ) ⬝ᵥ x := by
simp [Function.star_sum_elim, fromBlocks_mulVec, vecMul_fromBlocks, add_vecMul,
dotProduct_mulVec, vecMul_sub, Matrix.mul_assoc, vecMul_mulVec, hD.eq,
conjTranspose_nonsing_inv, star_mulVec]
@@ -537,7 +537,7 @@ theorem PosSemidef.fromBlocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A :
rw [PosSemidef, IsHermitian.fromBlocks₁₁ _ _ hA.1]
constructor
· refine' fun h => ⟨h.1, fun x => _⟩
- have := h.2 (-(A⁻¹ * B).mulVec x ⊕ᵥ x)
+ have := h.2 (-((A⁻¹ * B) *ᵥ x) ⊕ᵥ x)
rw [dotProduct_mulVec, schur_complement_eq₁₁ B D _ _ hA.1, neg_add_self, dotProduct_zero,
zero_add] at this
rw [dotProduct_mulVec]; exact this
@@ -459,16 +459,16 @@ theorem det_add_col_mul_row {A : Matrix m m α} (hA : IsUnit A.det) (u v : m →
(A + col u * row v).det = A.det * (1 + row v * A⁻¹ * col u).det := by
nth_rewrite 1 [← Matrix.mul_one A]
rwa [← Matrix.mul_nonsing_inv_cancel_left A (col u * row v),
- ←Matrix.mul_add, det_mul, ←Matrix.mul_assoc, det_one_add_mul_comm,
- ←Matrix.mul_assoc]
+ ← Matrix.mul_add, det_mul, ← Matrix.mul_assoc, det_one_add_mul_comm,
+ ← Matrix.mul_assoc]
/-- A generalization of the **Matrix determinant lemma** -/
theorem det_add_mul {A : Matrix m m α} (U : Matrix m n α)
(V : Matrix n m α) (hA : IsUnit A.det) :
(A + U * V).det = A.det * (1 + V * A⁻¹ * U).det := by
nth_rewrite 1 [← Matrix.mul_one A]
- rwa [← Matrix.mul_nonsing_inv_cancel_left A (U * V), ←Matrix.mul_add,
- det_mul, ←Matrix.mul_assoc, det_one_add_mul_comm, ←Matrix.mul_assoc]
+ rwa [← Matrix.mul_nonsing_inv_cancel_left A (U * V), ← Matrix.mul_add,
+ det_mul, ← Matrix.mul_assoc, det_one_add_mul_comm, ← Matrix.mul_assoc]
end Det
@@ -444,14 +444,32 @@ theorem det_one_sub_mul_comm (A : Matrix m n α) (B : Matrix n m α) :
rw [sub_eq_add_neg, ← Matrix.neg_mul, det_one_add_mul_comm, Matrix.mul_neg, ← sub_eq_add_neg]
#align matrix.det_one_sub_mul_comm Matrix.det_one_sub_mul_comm
-/-- A special case of the **Matrix determinant lemma** for when `A = I`.
-
-TODO: show this more generally. -/
+/-- A special case of the **Matrix determinant lemma** for when `A = I`. -/
theorem det_one_add_col_mul_row (u v : m → α) : det (1 + col u * row v) = 1 + v ⬝ᵥ u := by
rw [det_one_add_mul_comm, det_unique, Pi.add_apply, Pi.add_apply, Matrix.one_apply_eq,
Matrix.row_mul_col_apply]
#align matrix.det_one_add_col_mul_row Matrix.det_one_add_col_mul_row
+/-- The **Matrix determinant lemma**
+
+TODO: show the more general version without `hA : IsUnit A.det` as
+`(A + col u * row v).det = A.det + v ⬝ᵥ (adjugate A).mulVec u`.
+-/
+theorem det_add_col_mul_row {A : Matrix m m α} (hA : IsUnit A.det) (u v : m → α) :
+ (A + col u * row v).det = A.det * (1 + row v * A⁻¹ * col u).det := by
+ nth_rewrite 1 [← Matrix.mul_one A]
+ rwa [← Matrix.mul_nonsing_inv_cancel_left A (col u * row v),
+ ←Matrix.mul_add, det_mul, ←Matrix.mul_assoc, det_one_add_mul_comm,
+ ←Matrix.mul_assoc]
+
+/-- A generalization of the **Matrix determinant lemma** -/
+theorem det_add_mul {A : Matrix m m α} (U : Matrix m n α)
+ (V : Matrix n m α) (hA : IsUnit A.det) :
+ (A + U * V).det = A.det * (1 + V * A⁻¹ * U).det := by
+ nth_rewrite 1 [← Matrix.mul_one A]
+ rwa [← Matrix.mul_nonsing_inv_cancel_left A (U * V), ←Matrix.mul_add,
+ det_mul, ←Matrix.mul_assoc, det_one_add_mul_comm, ←Matrix.mul_assoc]
+
end Det
end CommRing
I assume this is mathematically sound, though right now we can't generalize many dependencies due to the reliance of InnerProductSpace
.
@@ -456,14 +456,12 @@ end Det
end CommRing
-/-! ### Lemmas about `ℝ` and `ℂ`-/
+/-! ### Lemmas about `ℝ` and `ℂ` and other `StarOrderedRing`s -/
-section IsROrC
+section StarOrderedRing
-open scoped Matrix
-
-variable {𝕜 : Type*} [IsROrC 𝕜]
+variable {𝕜 : Type*} [CommRing 𝕜] [PartialOrder 𝕜] [StarOrderedRing 𝕜]
scoped infixl:65 " ⊕ᵥ " => Sum.elim
@@ -526,7 +524,7 @@ theorem PosSemidef.fromBlocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A :
zero_add] at this
rw [dotProduct_mulVec]; exact this
· refine' fun h => ⟨h.1, fun x => _⟩
- rw [dotProduct_mulVec, ← Sum.elim_comp_inl_inr x, schur_complement_eq₁₁ B D _ _ hA.1, map_add]
+ rw [dotProduct_mulVec, ← Sum.elim_comp_inl_inr x, schur_complement_eq₁₁ B D _ _ hA.1]
apply le_add_of_nonneg_of_le
· rw [← dotProduct_mulVec]
apply hA.posSemidef.2
@@ -545,6 +543,6 @@ theorem PosSemidef.fromBlocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A :
| simp
#align matrix.pos_semidef.from_blocks₂₂ Matrix.PosSemidef.fromBlocks₂₂
-end IsROrC
+end StarOrderedRing
end Matrix
⬝
notation in favor of HMul
(#6487)
The main difficulty here is that *
has a slightly difference precedence to ⬝
. notably around smul
and neg
.
The other annoyance is that ↑U ⬝ A ⬝ ↑U⁻¹ : Matrix m m 𝔸
now has to be written U.val * A * (U⁻¹).val
in order to typecheck.
A downside of this change to consider: if you have a goal of A * (B * C) = (A * B) * C
, mul_assoc
now gives the illusion of matching, when in fact Matrix.mul_assoc
is needed. Previously the distinct symbol made it easy to avoid this mistake.
On the flipside, there is now no need to rewrite by Matrix.mul_eq_mul
all the time (indeed, the lemma is now removed).
@@ -12,7 +12,7 @@ import Mathlib.LinearAlgebra.Matrix.PosDef
/-! # 2×2 block matrices and the Schur complement
This file proves properties of 2×2 block matrices `[A B; C D]` that relate to the Schur complement
-`D - C⬝A⁻¹⬝B`.
+`D - C*A⁻¹*B`.
Some of the results here generalize to 2×2 matrices in a category, rather than just a ring. A few
results in this direction can be found in the file `CateogryTheory.Preadditive.Biproducts`,
@@ -54,10 +54,10 @@ Schur complement. -/
theorem fromBlocks_eq_of_invertible₁₁ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix l m α)
(D : Matrix l n α) [Invertible A] :
fromBlocks A B C D =
- fromBlocks 1 0 (C ⬝ ⅟ A) 1 ⬝ fromBlocks A 0 0 (D - C ⬝ ⅟ A ⬝ B) ⬝
- fromBlocks 1 (⅟ A ⬝ B) 0 1 := by
+ fromBlocks 1 0 (C * ⅟ A) 1 * fromBlocks A 0 0 (D - C * ⅟ A * B) *
+ fromBlocks 1 (⅟ A * B) 0 1 := by
simp only [fromBlocks_multiply, Matrix.mul_zero, Matrix.zero_mul, add_zero, zero_add,
- Matrix.one_mul, Matrix.mul_one, Matrix.invOf_mul_self, Matrix.mul_invOf_self_assoc,
+ Matrix.one_mul, Matrix.mul_one, invOf_mul_self, Matrix.mul_invOf_self_assoc,
Matrix.mul_invOf_mul_self_cancel, Matrix.mul_assoc, add_sub_cancel'_right]
#align matrix.from_blocks_eq_of_invertible₁₁ Matrix.fromBlocks_eq_of_invertible₁₁
@@ -66,8 +66,8 @@ Schur complement. -/
theorem fromBlocks_eq_of_invertible₂₂ (A : Matrix l m α) (B : Matrix l n α) (C : Matrix n m α)
(D : Matrix n n α) [Invertible D] :
fromBlocks A B C D =
- fromBlocks 1 (B ⬝ ⅟ D) 0 1 ⬝ fromBlocks (A - B ⬝ ⅟ D ⬝ C) 0 0 D ⬝
- fromBlocks 1 0 (⅟ D ⬝ C) 1 :=
+ fromBlocks 1 (B * ⅟ D) 0 1 * fromBlocks (A - B * ⅟ D * C) 0 0 D *
+ fromBlocks 1 0 (⅟ D * C) 1 :=
(Matrix.reindex (Equiv.sumComm _ _) (Equiv.sumComm _ _)).injective <| by
simpa [reindex_apply, Equiv.sumComm_symm, ← submatrix_mul_equiv _ _ _ (Equiv.sumComm n m), ←
submatrix_mul_equiv _ _ _ (Equiv.sumComm n l), Equiv.sumComm_apply,
@@ -82,9 +82,9 @@ section Triangular
/-- An upper-block-triangular matrix is invertible if its diagonal is. -/
def fromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
[Invertible A] [Invertible D] : Invertible (fromBlocks A B 0 D) :=
- invertibleOfLeftInverse _ (fromBlocks (⅟ A) (-⅟ A ⬝ B ⬝ ⅟ D) 0 (⅟ D)) <| by
+ invertibleOfLeftInverse _ (fromBlocks (⅟ A) (-(⅟ A * B * ⅟ D)) 0 (⅟ D)) <| by
simp_rw [fromBlocks_multiply, Matrix.mul_zero, Matrix.zero_mul, zero_add, add_zero,
- Matrix.neg_mul, Matrix.invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_right_neg,
+ Matrix.neg_mul, invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_right_neg,
fromBlocks_one]
#align matrix.from_blocks_zero₂₁_invertible Matrix.fromBlocksZero₂₁Invertible
@@ -92,23 +92,23 @@ def fromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m n α) (D :
def fromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
[Invertible A] [Invertible D] : Invertible (fromBlocks A 0 C D) :=
invertibleOfLeftInverse _
- (fromBlocks (⅟ A) 0 (-⅟ D ⬝ C ⬝ ⅟ A)
+ (fromBlocks (⅟ A) 0 (-(⅟ D * C * ⅟ A))
(⅟ D)) <| by -- a symmetry argument is more work than just copying the proof
simp_rw [fromBlocks_multiply, Matrix.mul_zero, Matrix.zero_mul, zero_add, add_zero,
- Matrix.neg_mul, Matrix.invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_left_neg,
+ Matrix.neg_mul, invOf_mul_self, Matrix.mul_invOf_mul_self_cancel, add_left_neg,
fromBlocks_one]
#align matrix.from_blocks_zero₁₂_invertible Matrix.fromBlocksZero₁₂Invertible
theorem invOf_fromBlocks_zero₂₁_eq (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
[Invertible A] [Invertible D] [Invertible (fromBlocks A B 0 D)] :
- ⅟ (fromBlocks A B 0 D) = fromBlocks (⅟ A) (-⅟ A ⬝ B ⬝ ⅟ D) 0 (⅟ D) := by
+ ⅟ (fromBlocks A B 0 D) = fromBlocks (⅟ A) (-(⅟ A * B * ⅟ D)) 0 (⅟ D) := by
letI := fromBlocksZero₂₁Invertible A B D
convert (rfl : ⅟ (fromBlocks A B 0 D) = _)
#align matrix.inv_of_from_blocks_zero₂₁_eq Matrix.invOf_fromBlocks_zero₂₁_eq
theorem invOf_fromBlocks_zero₁₂_eq (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
[Invertible A] [Invertible D] [Invertible (fromBlocks A 0 C D)] :
- ⅟ (fromBlocks A 0 C D) = fromBlocks (⅟ A) 0 (-⅟ D ⬝ C ⬝ ⅟ A) (⅟ D) := by
+ ⅟ (fromBlocks A 0 C D) = fromBlocks (⅟ A) 0 (-(⅟ D * C * ⅟ A)) (⅟ D) := by
letI := fromBlocksZero₁₂Invertible A C D
convert (rfl : ⅟ (fromBlocks A 0 C D) = _)
#align matrix.inv_of_from_blocks_zero₁₂_eq Matrix.invOf_fromBlocks_zero₁₂_eq
@@ -119,14 +119,14 @@ def invertibleOfFromBlocksZero₂₁Invertible (A : Matrix m m α) (B : Matrix m
[Invertible (fromBlocks A B 0 D)] : Invertible A × Invertible D where
fst :=
invertibleOfLeftInverse _ (⅟ (fromBlocks A B 0 D)).toBlocks₁₁ <| by
- have := Matrix.invOf_mul_self (fromBlocks A B 0 D)
+ have := invOf_mul_self (fromBlocks A B 0 D)
rw [← fromBlocks_toBlocks (⅟ (fromBlocks A B 0 D)), fromBlocks_multiply] at this
replace := congr_arg Matrix.toBlocks₁₁ this
simpa only [Matrix.toBlocks_fromBlocks₁₁, Matrix.mul_zero, add_zero, ← fromBlocks_one] using
this
snd :=
invertibleOfRightInverse _ (⅟ (fromBlocks A B 0 D)).toBlocks₂₂ <| by
- have := Matrix.mul_invOf_self (fromBlocks A B 0 D)
+ have := mul_invOf_self (fromBlocks A B 0 D)
rw [← fromBlocks_toBlocks (⅟ (fromBlocks A B 0 D)), fromBlocks_multiply] at this
replace := congr_arg Matrix.toBlocks₂₂ this
simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.zero_mul, zero_add, ← fromBlocks_one] using
@@ -139,14 +139,14 @@ def invertibleOfFromBlocksZero₁₂Invertible (A : Matrix m m α) (C : Matrix n
[Invertible (fromBlocks A 0 C D)] : Invertible A × Invertible D where
fst :=
invertibleOfRightInverse _ (⅟ (fromBlocks A 0 C D)).toBlocks₁₁ <| by
- have := Matrix.mul_invOf_self (fromBlocks A 0 C D)
+ have := mul_invOf_self (fromBlocks A 0 C D)
rw [← fromBlocks_toBlocks (⅟ (fromBlocks A 0 C D)), fromBlocks_multiply] at this
replace := congr_arg Matrix.toBlocks₁₁ this
simpa only [Matrix.toBlocks_fromBlocks₁₁, Matrix.zero_mul, add_zero, ← fromBlocks_one] using
this
snd :=
invertibleOfLeftInverse _ (⅟ (fromBlocks A 0 C D)).toBlocks₂₂ <| by
- have := Matrix.invOf_mul_self (fromBlocks A 0 C D)
+ have := invOf_mul_self (fromBlocks A 0 C D)
rw [← fromBlocks_toBlocks (⅟ (fromBlocks A 0 C D)), fromBlocks_multiply] at this
replace := congr_arg Matrix.toBlocks₂₂ this
simpa only [Matrix.toBlocks_fromBlocks₂₂, Matrix.mul_zero, zero_add, ← fromBlocks_one] using
@@ -203,7 +203,7 @@ theorem isUnit_fromBlocks_zero₁₂ {A : Matrix m m α} {C : Matrix n m α} {D
diagonal are invertible, or both are not. -/
theorem inv_fromBlocks_zero₂₁_of_isUnit_iff (A : Matrix m m α) (B : Matrix m n α) (D : Matrix n n α)
(hAD : IsUnit A ↔ IsUnit D) :
- (fromBlocks A B 0 D)⁻¹ = fromBlocks A⁻¹ (-A⁻¹ ⬝ B ⬝ D⁻¹) 0 D⁻¹ := by
+ (fromBlocks A B 0 D)⁻¹ = fromBlocks A⁻¹ (-(A⁻¹ * B * D⁻¹)) 0 D⁻¹ := by
by_cases hA : IsUnit A
· have hD := hAD.mp hA
cases hA.nonempty_invertible
@@ -221,7 +221,7 @@ theorem inv_fromBlocks_zero₂₁_of_isUnit_iff (A : Matrix m m α) (B : Matrix
diagonal are invertible, or both are not. -/
theorem inv_fromBlocks_zero₁₂_of_isUnit_iff (A : Matrix m m α) (C : Matrix n m α) (D : Matrix n n α)
(hAD : IsUnit A ↔ IsUnit D) :
- (fromBlocks A 0 C D)⁻¹ = fromBlocks A⁻¹ 0 (-D⁻¹ ⬝ C ⬝ A⁻¹) D⁻¹ := by
+ (fromBlocks A 0 C D)⁻¹ = fromBlocks A⁻¹ 0 (-(D⁻¹ * C * A⁻¹)) D⁻¹ := by
by_cases hA : IsUnit A
· have hD := hAD.mp hA
cases hA.nonempty_invertible
@@ -248,27 +248,27 @@ section Block
/-- A block matrix is invertible if the bottom right corner and the corresponding schur complement
is. -/
def fromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
- (D : Matrix n n α) [Invertible D] [Invertible (A - B ⬝ ⅟ D ⬝ C)] :
+ (D : Matrix n n α) [Invertible D] [Invertible (A - B * ⅟ D * C)] :
Invertible (fromBlocks A B C D) := by
-- factor `fromBlocks` via `fromBlocks_eq_of_invertible₂₂`, and state the inverse we expect
refine'
Invertible.copy' _ _
- (fromBlocks (⅟ (A - B ⬝ ⅟ D ⬝ C)) (-⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ B ⬝ ⅟ D)
- (-⅟ D ⬝ C ⬝ ⅟ (A - B ⬝ ⅟ D ⬝ C)) (⅟ D + ⅟ D ⬝ C ⬝ ⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ B ⬝ ⅟ D))
+ (fromBlocks (⅟ (A - B * ⅟ D * C)) (-(⅟ (A - B * ⅟ D * C) * B * ⅟ D))
+ (-(⅟ D * C * ⅟ (A - B * ⅟ D * C))) (⅟ D + ⅟ D * C * ⅟ (A - B * ⅟ D * C) * B * ⅟ D))
(fromBlocks_eq_of_invertible₂₂ _ _ _ _) _
· -- the product is invertible because all the factors are
letI : Invertible (1 : Matrix n n α) := invertibleOne
letI : Invertible (1 : Matrix m m α) := invertibleOne
- refine' Invertible.matrixMul _ (fromBlocksZero₁₂Invertible _ _ _)
+ refine' Invertible.mul _ (fromBlocksZero₁₂Invertible _ _ _)
exact
- Invertible.matrixMul (fromBlocksZero₂₁Invertible _ _ _)
+ Invertible.mul (fromBlocksZero₂₁Invertible _ _ _)
(fromBlocksZero₂₁Invertible _ _ _)
· -- unfold the `Invertible` instances to get the raw factors
show
_ =
- fromBlocks 1 0 (-1 ⬝ (⅟ D ⬝ C) ⬝ 1) 1 ⬝
- (fromBlocks (⅟ (A - B ⬝ ⅟ D ⬝ C)) (-⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ 0 ⬝ ⅟ D) 0 (⅟ D) ⬝
- fromBlocks 1 (-1 ⬝ (B ⬝ ⅟ D) ⬝ 1) 0 1)
+ fromBlocks 1 0 (-(1 * (⅟ D * C) * 1)) 1 *
+ (fromBlocks (⅟ (A - B * ⅟ D * C)) (-(⅟ (A - B * ⅟ D * C) * 0 * ⅟ D)) 0 (⅟ D) *
+ fromBlocks 1 (-(1 * (B * ⅟ D) * 1)) 0 1)
-- combine into a single block matrix
simp only [fromBlocks_multiply, invOf_one, Matrix.one_mul, Matrix.mul_one, Matrix.zero_mul,
Matrix.mul_zero, add_zero, zero_add, neg_zero, Matrix.mul_neg, Matrix.neg_mul, neg_neg, ←
@@ -278,7 +278,7 @@ def fromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matr
/-- A block matrix is invertible if the top left corner and the corresponding schur complement
is. -/
def fromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
- (D : Matrix n n α) [Invertible A] [Invertible (D - C ⬝ ⅟ A ⬝ B)] :
+ (D : Matrix n n α) [Invertible A] [Invertible (D - C * ⅟ A * B)] :
Invertible (fromBlocks A B C D) := by
-- we argue by symmetry
letI := fromBlocks₂₂Invertible D C B A
@@ -286,28 +286,28 @@ def fromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matr
submatrixEquivInvertible (fromBlocks D C B A) (Equiv.sumComm _ _) (Equiv.sumComm _ _)
exact
iDCBA.copy' _
- (fromBlocks (⅟ A + ⅟ A ⬝ B ⬝ ⅟ (D - C ⬝ ⅟ A ⬝ B) ⬝ C ⬝ ⅟ A) (-⅟ A ⬝ B ⬝ ⅟ (D - C ⬝ ⅟ A ⬝ B))
- (-⅟ (D - C ⬝ ⅟ A ⬝ B) ⬝ C ⬝ ⅟ A) (⅟ (D - C ⬝ ⅟ A ⬝ B)))
+ (fromBlocks (⅟ A + ⅟ A * B * ⅟ (D - C * ⅟ A * B) * C * ⅟ A) (-(⅟ A * B * ⅟ (D - C * ⅟ A * B)))
+ (-(⅟ (D - C * ⅟ A * B) * C * ⅟ A)) (⅟ (D - C * ⅟ A * B)))
(fromBlocks_submatrix_sum_swap_sum_swap _ _ _ _).symm
(fromBlocks_submatrix_sum_swap_sum_swap _ _ _ _).symm
#align matrix.from_blocks₁₁_invertible Matrix.fromBlocks₁₁Invertible
theorem invOf_fromBlocks₂₂_eq (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
- (D : Matrix n n α) [Invertible D] [Invertible (A - B ⬝ ⅟ D ⬝ C)]
+ (D : Matrix n n α) [Invertible D] [Invertible (A - B * ⅟ D * C)]
[Invertible (fromBlocks A B C D)] :
⅟ (fromBlocks A B C D) =
- fromBlocks (⅟ (A - B ⬝ ⅟ D ⬝ C)) (-⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ B ⬝ ⅟ D)
- (-⅟ D ⬝ C ⬝ ⅟ (A - B ⬝ ⅟ D ⬝ C)) (⅟ D + ⅟ D ⬝ C ⬝ ⅟ (A - B ⬝ ⅟ D ⬝ C) ⬝ B ⬝ ⅟ D) := by
+ fromBlocks (⅟ (A - B * ⅟ D * C)) (-(⅟ (A - B * ⅟ D * C) * B * ⅟ D))
+ (-(⅟ D * C * ⅟ (A - B * ⅟ D * C))) (⅟ D + ⅟ D * C * ⅟ (A - B * ⅟ D * C) * B * ⅟ D) := by
letI := fromBlocks₂₂Invertible A B C D
convert (rfl : ⅟ (fromBlocks A B C D) = _)
#align matrix.inv_of_from_blocks₂₂_eq Matrix.invOf_fromBlocks₂₂_eq
theorem invOf_fromBlocks₁₁_eq (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
- (D : Matrix n n α) [Invertible A] [Invertible (D - C ⬝ ⅟ A ⬝ B)]
+ (D : Matrix n n α) [Invertible A] [Invertible (D - C * ⅟ A * B)]
[Invertible (fromBlocks A B C D)] :
⅟ (fromBlocks A B C D) =
- fromBlocks (⅟ A + ⅟ A ⬝ B ⬝ ⅟ (D - C ⬝ ⅟ A ⬝ B) ⬝ C ⬝ ⅟ A) (-⅟ A ⬝ B ⬝ ⅟ (D - C ⬝ ⅟ A ⬝ B))
- (-⅟ (D - C ⬝ ⅟ A ⬝ B) ⬝ C ⬝ ⅟ A) (⅟ (D - C ⬝ ⅟ A ⬝ B)) := by
+ fromBlocks (⅟ A + ⅟ A * B * ⅟ (D - C * ⅟ A * B) * C * ⅟ A) (-(⅟ A * B * ⅟ (D - C * ⅟ A * B)))
+ (-(⅟ (D - C * ⅟ A * B) * C * ⅟ A)) (⅟ (D - C * ⅟ A * B)) := by
letI := fromBlocks₁₁Invertible A B C D
convert (rfl : ⅟ (fromBlocks A B C D) = _)
#align matrix.inv_of_from_blocks₁₁_eq Matrix.invOf_fromBlocks₁₁_eq
@@ -316,25 +316,25 @@ theorem invOf_fromBlocks₁₁_eq (A : Matrix m m α) (B : Matrix m n α) (C : M
Schur complement. -/
def invertibleOfFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
(D : Matrix n n α) [Invertible D] [Invertible (fromBlocks A B C D)] :
- Invertible (A - B ⬝ ⅟ D ⬝ C) := by
- suffices Invertible (fromBlocks (A - B ⬝ ⅟ D ⬝ C) 0 0 D) by
- exact (invertibleOfFromBlocksZero₁₂Invertible (A - B ⬝ ⅟ D ⬝ C) 0 D).1
+ Invertible (A - B * ⅟ D * C) := by
+ suffices Invertible (fromBlocks (A - B * ⅟ D * C) 0 0 D) by
+ exact (invertibleOfFromBlocksZero₁₂Invertible (A - B * ⅟ D * C) 0 D).1
letI : Invertible (1 : Matrix n n α) := invertibleOne
letI : Invertible (1 : Matrix m m α) := invertibleOne
- letI iDC : Invertible (fromBlocks 1 0 (⅟ D ⬝ C) 1 : Matrix (Sum m n) (Sum m n) α) :=
+ letI iDC : Invertible (fromBlocks 1 0 (⅟ D * C) 1 : Matrix (Sum m n) (Sum m n) α) :=
fromBlocksZero₁₂Invertible _ _ _
- letI iBD : Invertible (fromBlocks 1 (B ⬝ ⅟ D) 0 1 : Matrix (Sum m n) (Sum m n) α) :=
+ letI iBD : Invertible (fromBlocks 1 (B * ⅟ D) 0 1 : Matrix (Sum m n) (Sum m n) α) :=
fromBlocksZero₂₁Invertible _ _ _
letI iBDC := Invertible.copy ‹_› _ (fromBlocks_eq_of_invertible₂₂ A B C D).symm
- refine' (iBD.matrixMulLeft _).symm _
- refine' (iDC.matrixMulRight _).symm iBDC
+ refine' (iBD.mulLeft _).symm _
+ refine' (iDC.mulRight _).symm iBDC
#align matrix.invertible_of_from_blocks₂₂_invertible Matrix.invertibleOfFromBlocks₂₂Invertible
/-- If a block matrix is invertible and so is its bottom left element, then so is the corresponding
Schur complement. -/
def invertibleOfFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
(D : Matrix n n α) [Invertible A] [Invertible (fromBlocks A B C D)] :
- Invertible (D - C ⬝ ⅟ A ⬝ B) := by
+ Invertible (D - C * ⅟ A * B) := by
-- another symmetry argument
letI iABCD' :=
submatrixEquivInvertible (fromBlocks A B C D) (Equiv.sumComm _ _) (Equiv.sumComm _ _)
@@ -346,7 +346,7 @@ def invertibleOfFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n
equivalence. -/
def invertibleEquivFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
(D : Matrix n n α) [Invertible D] :
- Invertible (fromBlocks A B C D) ≃ Invertible (A - B ⬝ ⅟ D ⬝ C) where
+ Invertible (fromBlocks A B C D) ≃ Invertible (A - B * ⅟ D * C) where
toFun _iABCD := invertibleOfFromBlocks₂₂Invertible _ _ _ _
invFun _i_schur := fromBlocks₂₂Invertible _ _ _ _
left_inv _iABCD := Subsingleton.elim _ _
@@ -357,7 +357,7 @@ def invertibleEquivFromBlocks₂₂Invertible (A : Matrix m m α) (B : Matrix m
equivalence. -/
def invertibleEquivFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
(D : Matrix n n α) [Invertible A] :
- Invertible (fromBlocks A B C D) ≃ Invertible (D - C ⬝ ⅟ A ⬝ B) where
+ Invertible (fromBlocks A B C D) ≃ Invertible (D - C * ⅟ A * B) where
toFun _iABCD := invertibleOfFromBlocks₁₁Invertible _ _ _ _
invFun _i_schur := fromBlocks₁₁Invertible _ _ _ _
left_inv _iABCD := Subsingleton.elim _ _
@@ -368,7 +368,7 @@ def invertibleEquivFromBlocks₁₁Invertible (A : Matrix m m α) (B : Matrix m
iff the corresponding schur complement is. -/
theorem isUnit_fromBlocks_iff_of_invertible₂₂ {A : Matrix m m α} {B : Matrix m n α}
{C : Matrix n m α} {D : Matrix n n α} [Invertible D] :
- IsUnit (fromBlocks A B C D) ↔ IsUnit (A - B ⬝ ⅟ D ⬝ C) := by
+ IsUnit (fromBlocks A B C D) ↔ IsUnit (A - B * ⅟ D * C) := by
simp only [← nonempty_invertible_iff_isUnit,
(invertibleEquivFromBlocks₂₂Invertible A B C D).nonempty_congr]
#align matrix.is_unit_from_blocks_iff_of_invertible₂₂ Matrix.isUnit_fromBlocks_iff_of_invertible₂₂
@@ -377,7 +377,7 @@ theorem isUnit_fromBlocks_iff_of_invertible₂₂ {A : Matrix m m α} {B : Matri
iff the corresponding schur complement is. -/
theorem isUnit_fromBlocks_iff_of_invertible₁₁ {A : Matrix m m α} {B : Matrix m n α}
{C : Matrix n m α} {D : Matrix n n α} [Invertible A] :
- IsUnit (fromBlocks A B C D) ↔ IsUnit (D - C ⬝ ⅟ A ⬝ B) := by
+ IsUnit (fromBlocks A B C D) ↔ IsUnit (D - C * ⅟ A * B) := by
simp only [← nonempty_invertible_iff_isUnit,
(invertibleEquivFromBlocks₁₁Invertible A B C D).nonempty_congr]
#align matrix.is_unit_from_blocks_iff_of_invertible₁₁ Matrix.isUnit_fromBlocks_iff_of_invertible₁₁
@@ -393,14 +393,14 @@ section Det
the Schur complement. -/
theorem det_fromBlocks₁₁ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
(D : Matrix n n α) [Invertible A] :
- (Matrix.fromBlocks A B C D).det = det A * det (D - C ⬝ ⅟ A ⬝ B) := by
+ (Matrix.fromBlocks A B C D).det = det A * det (D - C * ⅟ A * B) := by
rw [fromBlocks_eq_of_invertible₁₁ (A := A), det_mul, det_mul, det_fromBlocks_zero₂₁,
det_fromBlocks_zero₂₁, det_fromBlocks_zero₁₂, det_one, det_one, one_mul, one_mul, mul_one]
#align matrix.det_from_blocks₁₁ Matrix.det_fromBlocks₁₁
@[simp]
theorem det_fromBlocks_one₁₁ (B : Matrix m n α) (C : Matrix n m α) (D : Matrix n n α) :
- (Matrix.fromBlocks 1 B C D).det = det (D - C ⬝ B) := by
+ (Matrix.fromBlocks 1 B C D).det = det (D - C * B) := by
haveI : Invertible (1 : Matrix m m α) := invertibleOne
rw [det_fromBlocks₁₁, invOf_one, Matrix.mul_one, det_one, one_mul]
#align matrix.det_from_blocks_one₁₁ Matrix.det_fromBlocks_one₁₁
@@ -409,7 +409,7 @@ theorem det_fromBlocks_one₁₁ (B : Matrix m n α) (C : Matrix n m α) (D : Ma
of the Schur complement. -/
theorem det_fromBlocks₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α)
(D : Matrix n n α) [Invertible D] :
- (Matrix.fromBlocks A B C D).det = det D * det (A - B ⬝ ⅟ D ⬝ C) := by
+ (Matrix.fromBlocks A B C D).det = det D * det (A - B * ⅟ D * C) := by
have : fromBlocks A B C D =
(fromBlocks D C B A).submatrix (Equiv.sumComm _ _) (Equiv.sumComm _ _) := by
ext (i j)
@@ -419,7 +419,7 @@ theorem det_fromBlocks₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix
@[simp]
theorem det_fromBlocks_one₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Matrix n m α) :
- (Matrix.fromBlocks A B C 1).det = det (A - B ⬝ C) := by
+ (Matrix.fromBlocks A B C 1).det = det (A - B * C) := by
haveI : Invertible (1 : Matrix n n α) := invertibleOne
rw [det_fromBlocks₂₂, invOf_one, Matrix.mul_one, det_one, one_mul]
#align matrix.det_from_blocks_one₂₂ Matrix.det_fromBlocks_one₂₂
@@ -427,27 +427,27 @@ theorem det_fromBlocks_one₂₂ (A : Matrix m m α) (B : Matrix m n α) (C : Ma
/-- The **Weinstein–Aronszajn identity**. Note the `1` on the LHS is of shape m×m, while the `1` on
the RHS is of shape n×n. -/
theorem det_one_add_mul_comm (A : Matrix m n α) (B : Matrix n m α) :
- det (1 + A ⬝ B) = det (1 + B ⬝ A) :=
+ det (1 + A * B) = det (1 + B * A) :=
calc
- det (1 + A ⬝ B) = det (fromBlocks 1 (-A) B 1) := by
+ det (1 + A * B) = det (fromBlocks 1 (-A) B 1) := by
rw [det_fromBlocks_one₂₂, Matrix.neg_mul, sub_neg_eq_add]
- _ = det (1 + B ⬝ A) := by rw [det_fromBlocks_one₁₁, Matrix.mul_neg, sub_neg_eq_add]
+ _ = det (1 + B * A) := by rw [det_fromBlocks_one₁₁, Matrix.mul_neg, sub_neg_eq_add]
#align matrix.det_one_add_mul_comm Matrix.det_one_add_mul_comm
/-- Alternate statement of the **Weinstein–Aronszajn identity** -/
theorem det_mul_add_one_comm (A : Matrix m n α) (B : Matrix n m α) :
- det (A ⬝ B + 1) = det (B ⬝ A + 1) := by rw [add_comm, det_one_add_mul_comm, add_comm]
+ det (A * B + 1) = det (B * A + 1) := by rw [add_comm, det_one_add_mul_comm, add_comm]
#align matrix.det_mul_add_one_comm Matrix.det_mul_add_one_comm
theorem det_one_sub_mul_comm (A : Matrix m n α) (B : Matrix n m α) :
- det (1 - A ⬝ B) = det (1 - B ⬝ A) := by
+ det (1 - A * B) = det (1 - B * A) := by
rw [sub_eq_add_neg, ← Matrix.neg_mul, det_one_add_mul_comm, Matrix.mul_neg, ← sub_eq_add_neg]
#align matrix.det_one_sub_mul_comm Matrix.det_one_sub_mul_comm
/-- A special case of the **Matrix determinant lemma** for when `A = I`.
TODO: show this more generally. -/
-theorem det_one_add_col_mul_row (u v : m → α) : det (1 + col u ⬝ row v) = 1 + v ⬝ᵥ u := by
+theorem det_one_add_col_mul_row (u v : m → α) : det (1 + col u * row v) = 1 + v ⬝ᵥ u := by
rw [det_one_add_mul_comm, det_unique, Pi.add_apply, Pi.add_apply, Matrix.one_apply_eq,
Matrix.row_mul_col_apply]
#align matrix.det_one_add_col_mul_row Matrix.det_one_add_col_mul_row
@@ -471,8 +471,8 @@ theorem schur_complement_eq₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A : M
(B : Matrix m n 𝕜) (D : Matrix n n 𝕜) (x : m → 𝕜) (y : n → 𝕜) [Invertible A]
(hA : A.IsHermitian) :
vecMul (star (x ⊕ᵥ y)) (fromBlocks A B Bᴴ D) ⬝ᵥ (x ⊕ᵥ y) =
- vecMul (star (x + (A⁻¹ ⬝ B).mulVec y)) A ⬝ᵥ (x + (A⁻¹ ⬝ B).mulVec y) +
- vecMul (star y) (D - Bᴴ ⬝ A⁻¹ ⬝ B) ⬝ᵥ y := by
+ vecMul (star (x + (A⁻¹ * B).mulVec y)) A ⬝ᵥ (x + (A⁻¹ * B).mulVec y) +
+ vecMul (star y) (D - Bᴴ * A⁻¹ * B) ⬝ᵥ y := by
simp [Function.star_sum_elim, fromBlocks_mulVec, vecMul_fromBlocks, add_vecMul,
dotProduct_mulVec, vecMul_sub, Matrix.mul_assoc, vecMul_mulVec, hA.eq,
conjTranspose_nonsing_inv, star_mulVec]
@@ -483,8 +483,8 @@ theorem schur_complement_eq₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : M
(B : Matrix m n 𝕜) {D : Matrix n n 𝕜} (x : m → 𝕜) (y : n → 𝕜) [Invertible D]
(hD : D.IsHermitian) :
vecMul (star (x ⊕ᵥ y)) (fromBlocks A B Bᴴ D) ⬝ᵥ (x ⊕ᵥ y) =
- vecMul (star ((D⁻¹ ⬝ Bᴴ).mulVec x + y)) D ⬝ᵥ ((D⁻¹ ⬝ Bᴴ).mulVec x + y) +
- vecMul (star x) (A - B ⬝ D⁻¹ ⬝ Bᴴ) ⬝ᵥ x := by
+ vecMul (star ((D⁻¹ * Bᴴ).mulVec x + y)) D ⬝ᵥ ((D⁻¹ * Bᴴ).mulVec x + y) +
+ vecMul (star x) (A - B * D⁻¹ * Bᴴ) ⬝ᵥ x := by
simp [Function.star_sum_elim, fromBlocks_mulVec, vecMul_fromBlocks, add_vecMul,
dotProduct_mulVec, vecMul_sub, Matrix.mul_assoc, vecMul_mulVec, hD.eq,
conjTranspose_nonsing_inv, star_mulVec]
@@ -493,8 +493,8 @@ theorem schur_complement_eq₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : M
theorem IsHermitian.fromBlocks₁₁ [Fintype m] [DecidableEq m] {A : Matrix m m 𝕜} (B : Matrix m n 𝕜)
(D : Matrix n n 𝕜) (hA : A.IsHermitian) :
- (Matrix.fromBlocks A B Bᴴ D).IsHermitian ↔ (D - Bᴴ ⬝ A⁻¹ ⬝ B).IsHermitian := by
- have hBAB : (Bᴴ ⬝ A⁻¹ ⬝ B).IsHermitian := by
+ (Matrix.fromBlocks A B Bᴴ D).IsHermitian ↔ (D - Bᴴ * A⁻¹ * B).IsHermitian := by
+ have hBAB : (Bᴴ * A⁻¹ * B).IsHermitian := by
apply isHermitian_conjTranspose_mul_mul
apply hA.inv
rw [isHermitian_fromBlocks_iff]
@@ -509,7 +509,7 @@ theorem IsHermitian.fromBlocks₁₁ [Fintype m] [DecidableEq m] {A : Matrix m m
theorem IsHermitian.fromBlocks₂₂ [Fintype n] [DecidableEq n] (A : Matrix m m 𝕜) (B : Matrix m n 𝕜)
{D : Matrix n n 𝕜} (hD : D.IsHermitian) :
- (Matrix.fromBlocks A B Bᴴ D).IsHermitian ↔ (A - B ⬝ D⁻¹ ⬝ Bᴴ).IsHermitian := by
+ (Matrix.fromBlocks A B Bᴴ D).IsHermitian ↔ (A - B * D⁻¹ * Bᴴ).IsHermitian := by
rw [← isHermitian_submatrix_equiv (Equiv.sumComm n m), Equiv.sumComm_apply,
fromBlocks_submatrix_sum_swap_sum_swap]
convert IsHermitian.fromBlocks₁₁ _ _ hD <;> simp
@@ -517,11 +517,11 @@ theorem IsHermitian.fromBlocks₂₂ [Fintype n] [DecidableEq n] (A : Matrix m m
theorem PosSemidef.fromBlocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A : Matrix m m 𝕜}
(B : Matrix m n 𝕜) (D : Matrix n n 𝕜) (hA : A.PosDef) [Invertible A] :
- (fromBlocks A B Bᴴ D).PosSemidef ↔ (D - Bᴴ ⬝ A⁻¹ ⬝ B).PosSemidef := by
+ (fromBlocks A B Bᴴ D).PosSemidef ↔ (D - Bᴴ * A⁻¹ * B).PosSemidef := by
rw [PosSemidef, IsHermitian.fromBlocks₁₁ _ _ hA.1]
constructor
· refine' fun h => ⟨h.1, fun x => _⟩
- have := h.2 (-(A⁻¹ ⬝ B).mulVec x ⊕ᵥ x)
+ have := h.2 (-(A⁻¹ * B).mulVec x ⊕ᵥ x)
rw [dotProduct_mulVec, schur_complement_eq₁₁ B D _ _ hA.1, neg_add_self, dotProduct_zero,
zero_add] at this
rw [dotProduct_mulVec]; exact this
@@ -536,7 +536,7 @@ theorem PosSemidef.fromBlocks₁₁ [Fintype m] [DecidableEq m] [Fintype n] {A :
theorem PosSemidef.fromBlocks₂₂ [Fintype m] [Fintype n] [DecidableEq n] (A : Matrix m m 𝕜)
(B : Matrix m n 𝕜) {D : Matrix n n 𝕜} (hD : D.PosDef) [Invertible D] :
- (fromBlocks A B Bᴴ D).PosSemidef ↔ (A - B ⬝ D⁻¹ ⬝ Bᴴ).PosSemidef := by
+ (fromBlocks A B Bᴴ D).PosSemidef ↔ (A - B * D⁻¹ * Bᴴ).PosSemidef := by
rw [← posSemidef_submatrix_equiv (Equiv.sumComm n m), Equiv.sumComm_apply,
fromBlocks_submatrix_sum_swap_sum_swap]
convert PosSemidef.fromBlocks₁₁ Bᴴ A hD <;>
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -35,7 +35,7 @@ Compare with `Matrix.invertibleOfFromBlocks₁₁Invertible`.
-/
-variable {l m n α : Type _}
+variable {l m n α : Type*}
namespace Matrix
@@ -463,7 +463,7 @@ section IsROrC
open scoped Matrix
-variable {𝕜 : Type _} [IsROrC 𝕜]
+variable {𝕜 : Type*} [IsROrC 𝕜]
scoped infixl:65 " ⊕ᵥ " => Sum.elim
@@ -15,7 +15,7 @@ This file proves properties of 2×2 block matrices `[A B; C D]` that relate to t
`D - C⬝A⁻¹⬝B`.
Some of the results here generalize to 2×2 matrices in a category, rather than just a ring. A few
-results in this direction can be found in the the file `CateogryTheory.Preadditive.Biproducts`,
+results in this direction can be found in the file `CateogryTheory.Preadditive.Biproducts`,
especially the declarations `CategoryTheory.Biprod.gaussian` and `CategoryTheory.Biprod.isoElim`.
Compare with `Matrix.invertibleOfFromBlocks₁₁Invertible`.
@@ -2,16 +2,13 @@
Copyright (c) 2022 Alexander Bentkamp. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Alexander Bentkamp, Eric Wieser, Jeremy Avigad, Johan Commelin
-
-! This file was ported from Lean 3 source module linear_algebra.matrix.schur_complement
-! leanprover-community/mathlib commit a176cb1219e300e85793d44583dede42377b51af
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Data.Matrix.Invertible
import Mathlib.LinearAlgebra.Matrix.NonsingularInverse
import Mathlib.LinearAlgebra.Matrix.PosDef
+#align_import linear_algebra.matrix.schur_complement from "leanprover-community/mathlib"@"a176cb1219e300e85793d44583dede42377b51af"
+
/-! # 2×2 block matrices and the Schur complement
This file proves properties of 2×2 block matrices `[A B; C D]` that relate to the Schur complement
@@ -194,7 +194,7 @@ theorem isUnit_fromBlocks_zero₂₁ {A : Matrix m m α} {B : Matrix m n α} {D
/-- A lower block-triangular matrix is invertible iff both elements of its diagonal are.
-This is a propositional form of `Matrix.fromBlocksZero₁₂InvertibleEquiv` forms an `iff`. -/
+This is a propositional form of `Matrix.fromBlocksZero₁₂InvertibleEquiv` forms an `iff`. -/
@[simp]
theorem isUnit_fromBlocks_zero₁₂ {A : Matrix m m α} {C : Matrix n m α} {D : Matrix n n α} :
IsUnit (fromBlocks A 0 C D) ↔ IsUnit A ∧ IsUnit D := by
The unported dependencies are
algebra.order.module
init.core
linear_algebra.free_module.finite.rank
algebra.order.monoid.cancel.defs
algebra.abs
algebra.group_power.lemmas
init.data.list.basic
linear_algebra.free_module.rank
init.data.list.default
algebra.order.monoid.cancel.basic
topology.subset_properties
init.logic
The following 1 dependencies have changed in mathlib3 since they were ported, which may complicate porting this file