File: Mathlib/Data/Matrix/Block.lean

full_name: Matrix.dotProduct_block
code: theorem dotProduct_block [Fintype m] [Fintype n] [Mul α] [AddCommMonoid α] (v w : m ⊕ n → α) :
    v ⬝ᵥ w = v ∘ Sum.inl ⬝ᵥ w ∘ Sum.inl + v ∘ Sum.inr ⬝ᵥ w ∘ Sum.inr 
goal: v ⬝ᵥ w = v ∘ Sum.inl ⬝ᵥ w ∘ Sum.inl + v ∘ Sum.inr ⬝ᵥ w ∘ Sum.inr

full_name: Matrix.fromBlocks
code: /-- We can form a single large matrix by flattening smaller 'block' matrices of compatible
dimensions. -/
@[pp_nodot]
def fromBlocks (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) :
    Matrix (n ⊕ o) (l ⊕ m) α 
goal: Matrix (n ⊕ o) (l ⊕ m) α

full_name: Matrix.fromBlocks_apply₁₁
code: @[simp]
theorem fromBlocks_apply₁₁ (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (i : n) (j : l) : fromBlocks A B C D (Sum.inl i) (Sum.inl j) = A i j 
goal: Matrix.fromBlocks A B C D (Sum.inl i) (Sum.inl j) = A i j

full_name: Matrix.fromBlocks_apply₁₂
code: @[simp]
theorem fromBlocks_apply₁₂ (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (i : n) (j : m) : fromBlocks A B C D (Sum.inl i) (Sum.inr j) = B i j 
goal: Matrix.fromBlocks A B C D (Sum.inl i) (Sum.inr j) = B i j

full_name: Matrix.fromBlocks_apply₂₁
code: @[simp]
theorem fromBlocks_apply₂₁ (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (i : o) (j : l) : fromBlocks A B C D (Sum.inr i) (Sum.inl j) = C i j 
goal: Matrix.fromBlocks A B C D (Sum.inr i) (Sum.inl j) = C i j

full_name: Matrix.fromBlocks_apply₂₂
code: @[simp]
theorem fromBlocks_apply₂₂ (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (i : o) (j : m) : fromBlocks A B C D (Sum.inr i) (Sum.inr j) = D i j 
goal: Matrix.fromBlocks A B C D (Sum.inr i) (Sum.inr j) = D i j

full_name: Matrix.toBlocks₁₁
code: /-- Given a matrix whose row and column indexes are sum types, we can extract the corresponding
"top left" submatrix. -/
def toBlocks₁₁ (M : Matrix (n ⊕ o) (l ⊕ m) α) : Matrix n l α 
goal: Matrix n l α

full_name: Matrix.toBlocks₁₂
code: /-- Given a matrix whose row and column indexes are sum types, we can extract the corresponding
"top right" submatrix. -/
def toBlocks₁₂ (M : Matrix (n ⊕ o) (l ⊕ m) α) : Matrix n m α 
goal: Matrix n m α

full_name: Matrix.toBlocks₂₁
code: /-- Given a matrix whose row and column indexes are sum types, we can extract the corresponding
"bottom left" submatrix. -/
def toBlocks₂₁ (M : Matrix (n ⊕ o) (l ⊕ m) α) : Matrix o l α 
goal: Matrix o l α

full_name: Matrix.toBlocks₂₂
code: /-- Given a matrix whose row and column indexes are sum types, we can extract the corresponding
"bottom right" submatrix. -/
def toBlocks₂₂ (M : Matrix (n ⊕ o) (l ⊕ m) α) : Matrix o m α 
goal: Matrix o m α

full_name: Matrix.fromBlocks_toBlocks
code: theorem fromBlocks_toBlocks (M : Matrix (n ⊕ o) (l ⊕ m) α) :
    fromBlocks M.toBlocks₁₁ M.toBlocks₁₂ M.toBlocks₂₁ M.toBlocks₂₂ = M 
goal: Matrix.fromBlocks M.toBlocks₁₁ M.toBlocks₁₂ M.toBlocks₂₁ M.toBlocks₂₂ = M

full_name: Matrix.toBlocks_fromBlocks₁₁
code: @[simp]
theorem toBlocks_fromBlocks₁₁ (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) : (fromBlocks A B C D).toBlocks₁₁ = A 
goal: (Matrix.fromBlocks A B C D).toBlocks₁₁ = A

full_name: Matrix.toBlocks_fromBlocks₁₂
code: @[simp]
theorem toBlocks_fromBlocks₁₂ (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) : (fromBlocks A B C D).toBlocks₁₂ = B 
goal: (Matrix.fromBlocks A B C D).toBlocks₁₂ = B

full_name: Matrix.toBlocks_fromBlocks₂₁
code: @[simp]
theorem toBlocks_fromBlocks₂₁ (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) : (fromBlocks A B C D).toBlocks₂₁ = C 
goal: (Matrix.fromBlocks A B C D).toBlocks₂₁ = C

full_name: Matrix.toBlocks_fromBlocks₂₂
code: @[simp]
theorem toBlocks_fromBlocks₂₂ (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) : (fromBlocks A B C D).toBlocks₂₂ = D 
goal: (Matrix.fromBlocks A B C D).toBlocks₂₂ = D

full_name: Matrix.ext_iff_blocks
code: /-- Two block matrices are equal if their blocks are equal. -/
theorem ext_iff_blocks {A B : Matrix (n ⊕ o) (l ⊕ m) α} :
    A = B ↔
      A.toBlocks₁₁ = B.toBlocks₁₁ ∧
        A.toBlocks₁₂ = B.toBlocks₁₂ ∧ A.toBlocks₂₁ = B.toBlocks₂₁ ∧ A.toBlocks₂₂ = B.toBlocks₂₂ 
goal: A = B ↔
  A.toBlocks₁₁ = B.toBlocks₁₁ ∧ A.toBlocks₁₂ = B.toBlocks₁₂ ∧ A.toBlocks₂₁ = B.toBlocks₂₁ ∧ A.toBlocks₂₂ = B.toBlocks₂₂

full_name: Matrix.fromBlocks_inj
code: @[simp]
theorem fromBlocks_inj {A : Matrix n l α} {B : Matrix n m α} {C : Matrix o l α} {D : Matrix o m α}
    {A' : Matrix n l α} {B' : Matrix n m α} {C' : Matrix o l α} {D' : Matrix o m α} :
    fromBlocks A B C D = fromBlocks A' B' C' D' ↔ A = A' ∧ B = B' ∧ C = C' ∧ D = D' 
goal: Matrix.fromBlocks A B C D = Matrix.fromBlocks A' B' C' D' ↔ A = A' ∧ B = B' ∧ C = C' ∧ D = D'

full_name: Matrix.fromBlocks_map
code: theorem fromBlocks_map (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α)
    (f : α → β) : (fromBlocks A B C D).map f =
      fromBlocks (A.map f) (B.map f) (C.map f) (D.map f) 
goal: (Matrix.fromBlocks A B C D).map f = Matrix.fromBlocks (A.map f) (B.map f) (C.map f) (D.map f)

full_name: Matrix.fromBlocks_transpose
code: theorem fromBlocks_transpose (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) : (fromBlocks A B C D)ᵀ = fromBlocks Aᵀ Cᵀ Bᵀ Dᵀ 
goal: (Matrix.fromBlocks A B C D)ᵀ = Matrix.fromBlocks Aᵀ Cᵀ Bᵀ Dᵀ

full_name: Matrix.fromBlocks_conjTranspose
code: theorem fromBlocks_conjTranspose [Star α] (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) : (fromBlocks A B C D)ᴴ = fromBlocks Aᴴ Cᴴ Bᴴ Dᴴ 
goal: (Matrix.fromBlocks A B C D)ᴴ = Matrix.fromBlocks Aᴴ Cᴴ Bᴴ Dᴴ

full_name: Matrix.fromBlocks_submatrix_sum_swap_left
code: @[simp]
theorem fromBlocks_submatrix_sum_swap_left (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (f : p → l ⊕ m) :
    (fromBlocks A B C D).submatrix Sum.swap f = (fromBlocks C D A B).submatrix id f 
goal: (Matrix.fromBlocks A B C D).submatrix Sum.swap f = (Matrix.fromBlocks C D A B).submatrix id f

full_name: Matrix.fromBlocks_submatrix_sum_swap_right
code: @[simp]
theorem fromBlocks_submatrix_sum_swap_right (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (f : p → n ⊕ o) :
    (fromBlocks A B C D).submatrix f Sum.swap = (fromBlocks B A D C).submatrix f id 
goal: (Matrix.fromBlocks A B C D).submatrix f Sum.swap = (Matrix.fromBlocks B A D C).submatrix f id

full_name: Matrix.fromBlocks_submatrix_sum_swap_sum_swap
code: theorem fromBlocks_submatrix_sum_swap_sum_swap {l m n o α : Type*} (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) :
    (fromBlocks A B C D).submatrix Sum.swap Sum.swap = fromBlocks D C B A 
goal: (Matrix.fromBlocks A B C D).submatrix Sum.swap Sum.swap = Matrix.fromBlocks D C B A

full_name: Matrix.IsTwoBlockDiagonal
code: /-- A 2x2 block matrix is block diagonal if the blocks outside of the diagonal vanish -/
def IsTwoBlockDiagonal [Zero α] (A : Matrix (n ⊕ o) (l ⊕ m) α) : Prop 
goal: Prop

full_name: Matrix.toBlock
code: /-- Let `p` pick out certain rows and `q` pick out certain columns of a matrix `M`. Then
  `toBlock M p q` is the corresponding block matrix. -/
def toBlock (M : Matrix m n α) (p : m → Prop) (q : n → Prop) : Matrix { a // p a } { a // q a } α 
goal: Matrix { a // p a } { a // q a } α

full_name: Matrix.toBlock_apply
code: @[simp]
theorem toBlock_apply (M : Matrix m n α) (p : m → Prop) (q : n → Prop) (i : { a // p a })
    (j : { a // q a }) : toBlock M p q i j = M ↑i ↑j 
goal: M.toBlock p q i j = M ↑i ↑j

full_name: Matrix.toSquareBlockProp
code: /-- Let `p` pick out certain rows and columns of a square matrix `M`. Then
  `toSquareBlockProp M p` is the corresponding block matrix. -/
def toSquareBlockProp (M : Matrix m m α) (p : m → Prop) : Matrix { a // p a } { a // p a } α 
goal: Matrix { a // p a } { a // p a } α

full_name: Matrix.toSquareBlockProp_def
code: theorem toSquareBlockProp_def (M : Matrix m m α) (p : m → Prop) :
    -- Porting note: added missing `of`
    toSquareBlockProp M p = of (fun i j : { a // p a } => M ↑i ↑j) 
goal: M.toSquareBlockProp p = Matrix.of fun i j => M ↑i ↑j

full_name: Matrix.toSquareBlock
code: /-- Let `b` map rows and columns of a square matrix `M` to blocks. Then
  `toSquareBlock M b k` is the block `k` matrix. -/
def toSquareBlock (M : Matrix m m α) (b : m → β) (k : β) :
    Matrix { a // b a = k } { a // b a = k } α 
goal: Matrix { a // b a = k } { a // b a = k } α

full_name: Matrix.toSquareBlock_def
code: theorem toSquareBlock_def (M : Matrix m m α) (b : m → β) (k : β) :
    -- Porting note: added missing `of`
    toSquareBlock M b k = of (fun i j : { a // b a = k } => M ↑i ↑j) 
goal: M.toSquareBlock b k = Matrix.of fun i j => M ↑i ↑j

full_name: Matrix.fromBlocks_smul
code: theorem fromBlocks_smul [SMul R α] (x : R) (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) : x • fromBlocks A B C D = fromBlocks (x • A) (x • B) (x • C) (x • D) 
goal: x • Matrix.fromBlocks A B C D = Matrix.fromBlocks (x • A) (x • B) (x • C) (x • D)

full_name: Matrix.fromBlocks_neg
code: theorem fromBlocks_neg [Neg R] (A : Matrix n l R) (B : Matrix n m R) (C : Matrix o l R)
    (D : Matrix o m R) : -fromBlocks A B C D = fromBlocks (-A) (-B) (-C) (-D) 
goal: -Matrix.fromBlocks A B C D = Matrix.fromBlocks (-A) (-B) (-C) (-D)

full_name: Matrix.fromBlocks_zero
code: @[simp]
theorem fromBlocks_zero [Zero α] : fromBlocks (0 : Matrix n l α) 0 0 (0 : Matrix o m α) = 0 
goal: Matrix.fromBlocks 0 0 0 0 = 0

full_name: Matrix.fromBlocks_add
code: theorem fromBlocks_add [Add α] (A : Matrix n l α) (B : Matrix n m α) (C : Matrix o l α)
    (D : Matrix o m α) (A' : Matrix n l α) (B' : Matrix n m α) (C' : Matrix o l α)
    (D' : Matrix o m α) : fromBlocks A B C D + fromBlocks A' B' C' D' =
      fromBlocks (A + A') (B + B') (C + C') (D + D') 
goal: Matrix.fromBlocks A B C D + Matrix.fromBlocks A' B' C' D' = Matrix.fromBlocks (A + A') (B + B') (C + C') (D + D')

full_name: Matrix.fromBlocks_multiply
code: theorem fromBlocks_multiply [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (A' : Matrix l p α) (B' : Matrix l q α)
    (C' : Matrix m p α) (D' : Matrix m q α) :
    fromBlocks A B C D * fromBlocks A' B' C' D' =
      fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D') 
goal: Matrix.fromBlocks A B C D * Matrix.fromBlocks A' B' C' D' =
  Matrix.fromBlocks (A * A' + B * C') (A * B' + B * D') (C * A' + D * C') (C * B' + D * D')

full_name: Matrix.fromBlocks_mulVec
code: theorem fromBlocks_mulVec [Fintype l] [Fintype m] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : l ⊕ m → α) :
    (fromBlocks A B C D) *ᵥ x =
      Sum.elim (A *ᵥ (x ∘ Sum.inl) + B *ᵥ (x ∘ Sum.inr))
        (C *ᵥ (x ∘ Sum.inl) + D *ᵥ (x ∘ Sum.inr)) 
goal: Matrix.fromBlocks A B C D *ᵥ x = Sum.elim (A *ᵥ x ∘ Sum.inl + B *ᵥ x ∘ Sum.inr) (C *ᵥ x ∘ Sum.inl + D *ᵥ x ∘ Sum.inr)

full_name: Matrix.vecMul_fromBlocks
code: theorem vecMul_fromBlocks [Fintype n] [Fintype o] [NonUnitalNonAssocSemiring α] (A : Matrix n l α)
    (B : Matrix n m α) (C : Matrix o l α) (D : Matrix o m α) (x : n ⊕ o → α) :
    x ᵥ* fromBlocks A B C D =
      Sum.elim ((x ∘ Sum.inl) ᵥ* A + (x ∘ Sum.inr) ᵥ* C)
        ((x ∘ Sum.inl) ᵥ* B + (x ∘ Sum.inr) ᵥ* D) 
goal: x ᵥ* Matrix.fromBlocks A B C D = Sum.elim (x ∘ Sum.inl ᵥ* A + x ∘ Sum.inr ᵥ* C) (x ∘ Sum.inl ᵥ* B + x ∘ Sum.inr ᵥ* D)

full_name: Matrix.toBlock_diagonal_self
code: theorem toBlock_diagonal_self (d : m → α) (p : m → Prop) :
    Matrix.toBlock (diagonal d) p p = diagonal fun i : Subtype p => d ↑i 
goal: (Matrix.diagonal d).toBlock p p = Matrix.diagonal fun i => d ↑i

full_name: Matrix.toBlock_diagonal_disjoint
code: theorem toBlock_diagonal_disjoint (d : m → α) {p q : m → Prop} (hpq : Disjoint p q) :
    Matrix.toBlock (diagonal d) p q = 0 
goal: (Matrix.diagonal d).toBlock p q = 0

full_name: Matrix.fromBlocks_diagonal
code: @[simp]
theorem fromBlocks_diagonal (d₁ : l → α) (d₂ : m → α) :
    fromBlocks (diagonal d₁) 0 0 (diagonal d₂) = diagonal (Sum.elim d₁ d₂) 
goal: Matrix.fromBlocks (Matrix.diagonal d₁) 0 0 (Matrix.diagonal d₂) = Matrix.diagonal (Sum.elim d₁ d₂)

full_name: Matrix.toBlocks₁₁_diagonal
code: @[simp]
lemma toBlocks₁₁_diagonal (v : l ⊕ m → α) :
    toBlocks₁₁ (diagonal v) = diagonal (fun i => v (Sum.inl i)) 
goal: (Matrix.diagonal v).toBlocks₁₁ = Matrix.diagonal fun i => v (Sum.inl i)

full_name: Matrix.toBlocks₂₂_diagonal
code: @[simp]
lemma toBlocks₂₂_diagonal (v : l ⊕ m → α) :
    toBlocks₂₂ (diagonal v) = diagonal (fun i => v (Sum.inr i)) 
goal: (Matrix.diagonal v).toBlocks₂₂ = Matrix.diagonal fun i => v (Sum.inr i)

full_name: Matrix.toBlocks₁₂_diagonal
code: @[simp]
lemma toBlocks₁₂_diagonal (v : l ⊕ m → α) : toBlocks₁₂ (diagonal v) = 0 
goal: (Matrix.diagonal v).toBlocks₁₂ = 0

full_name: Matrix.toBlocks₂₁_diagonal
code: @[simp]
lemma toBlocks₂₁_diagonal (v : l ⊕ m → α) : toBlocks₂₁ (diagonal v) = 0 
goal: (Matrix.diagonal v).toBlocks₂₁ = 0

full_name: Matrix.fromBlocks_one
code: @[simp]
theorem fromBlocks_one : fromBlocks (1 : Matrix l l α) 0 0 (1 : Matrix m m α) = 1 
goal: Matrix.fromBlocks 1 0 0 1 = 1

full_name: Matrix.toBlock_one_self
code: @[simp]
theorem toBlock_one_self (p : m → Prop) : Matrix.toBlock (1 : Matrix m m α) p p = 1 
goal: Matrix.toBlock 1 p p = 1

full_name: Matrix.toBlock_one_disjoint
code: theorem toBlock_one_disjoint {p q : m → Prop} (hpq : Disjoint p q) :
    Matrix.toBlock (1 : Matrix m m α) p q = 0 
goal: Matrix.toBlock 1 p q = 0

full_name: Matrix.blockDiagonal
code: /-- `Matrix.blockDiagonal M` turns a homogenously-indexed collection of matrices
`M : o → Matrix m n α'` into an `m × o`-by-`n × o` block matrix which has the entries of `M` along
the diagonal and zero elsewhere.

See also `Matrix.blockDiagonal'` if the matrices may not have the same size everywhere.
-/
def blockDiagonal (M : o → Matrix m n α) : Matrix (m × o) (n × o) α 
goal: Matrix (m × o) (n × o) α

full_name: Matrix.blockDiagonal_apply'
code: theorem blockDiagonal_apply' (M : o → Matrix m n α) (i k j k') :
    blockDiagonal M ⟨i, k⟩ ⟨j, k'⟩ = if k = k' then M k i j else 0 
goal: Matrix.blockDiagonal M (i, k) (j, k') = if k = k' then M k i j else 0

full_name: Matrix.blockDiagonal_apply
code: theorem blockDiagonal_apply (M : o → Matrix m n α) (ik jk) :
    blockDiagonal M ik jk = if ik.2 = jk.2 then M ik.2 ik.1 jk.1 else 0 
goal: Matrix.blockDiagonal M ik jk = if ik.2 = jk.2 then M ik.2 ik.1 jk.1 else 0

full_name: Matrix.blockDiagonal_apply_eq
code: @[simp]
theorem blockDiagonal_apply_eq (M : o → Matrix m n α) (i j k) :
    blockDiagonal M (i, k) (j, k) = M k i j 
goal: Matrix.blockDiagonal M (i, k) (j, k) = M k i j

full_name: Matrix.blockDiagonal_apply_ne
code: theorem blockDiagonal_apply_ne (M : o → Matrix m n α) (i j) {k k'} (h : k ≠ k') :
    blockDiagonal M (i, k) (j, k') = 0 
goal: Matrix.blockDiagonal M (i, k) (j, k') = 0

full_name: Matrix.blockDiagonal_map
code: theorem blockDiagonal_map (M : o → Matrix m n α) (f : α → β) (hf : f 0 = 0) :
    (blockDiagonal M).map f = blockDiagonal fun k => (M k).map f 
goal: (Matrix.blockDiagonal M).map f = Matrix.blockDiagonal fun k => (M k).map f

full_name: Matrix.blockDiagonal_transpose
code: @[simp]
theorem blockDiagonal_transpose (M : o → Matrix m n α) :
    (blockDiagonal M)ᵀ = blockDiagonal fun k => (M k)ᵀ 
goal: (Matrix.blockDiagonal M)ᵀ = Matrix.blockDiagonal fun k => (M k)ᵀ

full_name: Matrix.blockDiagonal_conjTranspose
code: @[simp]
theorem blockDiagonal_conjTranspose {α : Type*} [AddMonoid α] [StarAddMonoid α]
    (M : o → Matrix m n α) : (blockDiagonal M)ᴴ = blockDiagonal fun k => (M k)ᴴ 
goal: (Matrix.blockDiagonal M)ᴴ = Matrix.blockDiagonal fun k => (M k)ᴴ

full_name: Matrix.blockDiagonal_zero
code: @[simp]
theorem blockDiagonal_zero : blockDiagonal (0 : o → Matrix m n α) = 0 
goal: Matrix.blockDiagonal 0 = 0

full_name: Matrix.blockDiagonal_diagonal
code: @[simp]
theorem blockDiagonal_diagonal [DecidableEq m] (d : o → m → α) :
    (blockDiagonal fun k => diagonal (d k)) = diagonal fun ik => d ik.2 ik.1 
goal: (Matrix.blockDiagonal fun k => Matrix.diagonal (d k)) = Matrix.diagonal fun ik => d ik.2 ik.1

full_name: Matrix.blockDiagonal_one
code: @[simp]
theorem blockDiagonal_one [DecidableEq m] [One α] : blockDiagonal (1 : o → Matrix m m α) = 1 
goal: Matrix.blockDiagonal 1 = 1

full_name: Matrix.blockDiagonal_add
code: @[simp]
theorem blockDiagonal_add [AddZeroClass α] (M N : o → Matrix m n α) :
    blockDiagonal (M + N) = blockDiagonal M + blockDiagonal N 
goal: Matrix.blockDiagonal (M + N) = Matrix.blockDiagonal M + Matrix.blockDiagonal N

full_name: Matrix.blockDiagonalAddMonoidHom
code: /-- `Matrix.blockDiagonal` as an `AddMonoidHom`. -/
@[simps]
def blockDiagonalAddMonoidHom [AddZeroClass α] :
    (o → Matrix m n α) →+ Matrix (m × o) (n × o) α 
goal: (o → Matrix m n α) →+ Matrix (m × o) (n × o) α

full_name: Matrix.blockDiagonalAddMonoidHom_apply
code: /-- `Matrix.blockDiagonal` as an `AddMonoidHom`. -/
@[simps]
def blockDiagonalAddMonoidHom [AddZeroClass α] :
    (o → Matrix m n α) →+ Matrix (m × o) (n × o) α 
goal: (Matrix.blockDiagonalAddMonoidHom m n o α) M = Matrix.blockDiagonal M

full_name: Matrix.blockDiagonal_neg
code: @[simp]
theorem blockDiagonal_neg [AddGroup α] (M : o → Matrix m n α) :
    blockDiagonal (-M) = -blockDiagonal M 
goal: Matrix.blockDiagonal (-M) = -Matrix.blockDiagonal M

full_name: Matrix.blockDiagonal_sub
code: @[simp]
theorem blockDiagonal_sub [AddGroup α] (M N : o → Matrix m n α) :
    blockDiagonal (M - N) = blockDiagonal M - blockDiagonal N 
goal: Matrix.blockDiagonal (M - N) = Matrix.blockDiagonal M - Matrix.blockDiagonal N

full_name: Matrix.blockDiagonal_mul
code: @[simp]
theorem blockDiagonal_mul [Fintype n] [Fintype o] [NonUnitalNonAssocSemiring α]
    (M : o → Matrix m n α) (N : o → Matrix n p α) :
    (blockDiagonal fun k => M k * N k) = blockDiagonal M * blockDiagonal N 
goal: (Matrix.blockDiagonal fun k => M k * N k) = Matrix.blockDiagonal M * Matrix.blockDiagonal N

full_name: Matrix.blockDiagonalRingHom_apply
code: /-- `Matrix.blockDiagonal` as a `RingHom`. -/
@[simps]
def blockDiagonalRingHom [DecidableEq m] [Fintype o] [Fintype m] [NonAssocSemiring α] :
    (o → Matrix m m α) →+* Matrix (m × o) (m × o) α 
goal: (Matrix.blockDiagonalRingHom m o α) M = Matrix.blockDiagonal M

full_name: Matrix.blockDiagonalRingHom
code: /-- `Matrix.blockDiagonal` as a `RingHom`. -/
@[simps]
def blockDiagonalRingHom [DecidableEq m] [Fintype o] [Fintype m] [NonAssocSemiring α] :
    (o → Matrix m m α) →+* Matrix (m × o) (m × o) α 
goal: (o → Matrix m m α) →+* Matrix (m × o) (m × o) α

full_name: Matrix.blockDiagonal_pow
code: @[simp]
theorem blockDiagonal_pow [DecidableEq m] [Fintype o] [Fintype m] [Semiring α]
    (M : o → Matrix m m α) (n : ℕ) : blockDiagonal (M ^ n) = blockDiagonal M ^ n 
goal: Matrix.blockDiagonal (M ^ n) = Matrix.blockDiagonal M ^ n

full_name: Matrix.blockDiagonal_smul
code: @[simp]
theorem blockDiagonal_smul {R : Type*} [Monoid R] [AddMonoid α] [DistribMulAction R α] (x : R)
    (M : o → Matrix m n α) : blockDiagonal (x • M) = x • blockDiagonal M 
goal: Matrix.blockDiagonal (x • M) = x • Matrix.blockDiagonal M

full_name: Matrix.blockDiag
code: /-- Extract a block from the diagonal of a block diagonal matrix.

This is the block form of `Matrix.diag`, and the left-inverse of `Matrix.blockDiagonal`. -/
def blockDiag (M : Matrix (m × o) (n × o) α) (k : o) : Matrix m n α 
goal: Matrix m n α

full_name: Matrix.blockDiag_apply
code: theorem blockDiag_apply (M : Matrix (m × o) (n × o) α) (k : o) (i j) :
    blockDiag M k i j = M (i, k) (j, k) 
goal: M.blockDiag k i j = M (i, k) (j, k)

full_name: Matrix.blockDiag_map
code: theorem blockDiag_map (M : Matrix (m × o) (n × o) α) (f : α → β) :
    blockDiag (M.map f) = fun k => (blockDiag M k).map f 
goal: (M.map f).blockDiag = fun k => (M.blockDiag k).map f

full_name: Matrix.blockDiag_transpose
code: @[simp]
theorem blockDiag_transpose (M : Matrix (m × o) (n × o) α) (k : o) :
    blockDiag Mᵀ k = (blockDiag M k)ᵀ 
goal: Mᵀ.blockDiag k = (M.blockDiag k)ᵀ

full_name: Matrix.blockDiag_conjTranspose
code: @[simp]
theorem blockDiag_conjTranspose {α : Type*} [AddMonoid α] [StarAddMonoid α]
    (M : Matrix (m × o) (n × o) α) (k : o) : blockDiag Mᴴ k = (blockDiag M k)ᴴ 
goal: Mᴴ.blockDiag k = (M.blockDiag k)ᴴ

full_name: Matrix.blockDiag_zero
code: @[simp]
theorem blockDiag_zero : blockDiag (0 : Matrix (m × o) (n × o) α) = 0 
goal: Matrix.blockDiag 0 = 0

full_name: Matrix.blockDiag_diagonal
code: @[simp]
theorem blockDiag_diagonal [DecidableEq o] [DecidableEq m] (d : m × o → α) (k : o) :
    blockDiag (diagonal d) k = diagonal fun i => d (i, k) 
goal: (Matrix.diagonal d).blockDiag k = Matrix.diagonal fun i => d (i, k)

full_name: Matrix.blockDiag_blockDiagonal
code: @[simp]
theorem blockDiag_blockDiagonal [DecidableEq o] (M : o → Matrix m n α) :
    blockDiag (blockDiagonal M) = M 
goal: (Matrix.blockDiagonal M).blockDiag = M

full_name: Matrix.blockDiagonal_injective
code: theorem blockDiagonal_injective [DecidableEq o] :
    Function.Injective (blockDiagonal : (o → Matrix m n α) → Matrix _ _ α) 
goal: Function.Injective Matrix.blockDiagonal

full_name: Matrix.blockDiagonal_inj
code: @[simp]
theorem blockDiagonal_inj [DecidableEq o] {M N : o → Matrix m n α} :
    blockDiagonal M = blockDiagonal N ↔ M = N 
goal: Matrix.blockDiagonal M = Matrix.blockDiagonal N ↔ M = N

full_name: Matrix.blockDiag_one
code: @[simp]
theorem blockDiag_one [DecidableEq o] [DecidableEq m] [One α] :
    blockDiag (1 : Matrix (m × o) (m × o) α) = 1 
goal: Matrix.blockDiag 1 = 1

full_name: Matrix.blockDiag_add
code: @[simp]
theorem blockDiag_add [AddZeroClass α] (M N : Matrix (m × o) (n × o) α) :
    blockDiag (M + N) = blockDiag M + blockDiag N 
goal: (M + N).blockDiag = M.blockDiag + N.blockDiag

full_name: Matrix.blockDiagAddMonoidHom
code: /-- `Matrix.blockDiag` as an `AddMonoidHom`. -/
@[simps]
def blockDiagAddMonoidHom [AddZeroClass α] : Matrix (m × o) (n × o) α →+ o → Matrix m n α 
goal: Matrix (m × o) (n × o) α →+ o → Matrix m n α

full_name: Matrix.blockDiagAddMonoidHom_apply
code: /-- `Matrix.blockDiag` as an `AddMonoidHom`. -/
@[simps]
def blockDiagAddMonoidHom [AddZeroClass α] : Matrix (m × o) (n × o) α →+ o → Matrix m n α 
goal: (Matrix.blockDiagAddMonoidHom m n o α) M k = M.blockDiag k

full_name: Matrix.blockDiag_neg
code: @[simp]
theorem blockDiag_neg [AddGroup α] (M : Matrix (m × o) (n × o) α) : blockDiag (-M) = -blockDiag M 
goal: (-M).blockDiag = -M.blockDiag

full_name: Matrix.blockDiag_sub
code: @[simp]
theorem blockDiag_sub [AddGroup α] (M N : Matrix (m × o) (n × o) α) :
    blockDiag (M - N) = blockDiag M - blockDiag N 
goal: (M - N).blockDiag = M.blockDiag - N.blockDiag

full_name: Matrix.blockDiag_smul
code: @[simp]
theorem blockDiag_smul {R : Type*} [Monoid R] [AddMonoid α] [DistribMulAction R α] (x : R)
    (M : Matrix (m × o) (n × o) α) : blockDiag (x • M) = x • blockDiag M 
goal: (x • M).blockDiag = x • M.blockDiag

full_name: Matrix.blockDiagonal'
code: /-- `Matrix.blockDiagonal' M` turns `M : Π i, Matrix (m i) (n i) α` into a
`Σ i, m i`-by-`Σ i, n i` block matrix which has the entries of `M` along the diagonal
and zero elsewhere.

This is the dependently-typed version of `Matrix.blockDiagonal`. -/
def blockDiagonal' (M : ∀ i, Matrix (m' i) (n' i) α) : Matrix (Σi, m' i) (Σi, n' i) α 
goal: Matrix ((i : o) × m' i) ((i : o) × n' i) α

full_name: Matrix.blockDiagonal'_apply'
code: theorem blockDiagonal'_apply' (M : ∀ i, Matrix (m' i) (n' i) α) (k i k' j) :
    blockDiagonal' M ⟨k, i⟩ ⟨k', j⟩ =
      if h : k = k' then M k i (cast (congr_arg n' h.symm) j) else 0 
goal: Matrix.blockDiagonal' M ⟨k, i⟩ ⟨k', j⟩ = if h : k = k' then M k i (cast ⋯ j) else 0

full_name: Matrix.blockDiagonal'_eq_blockDiagonal
code: theorem blockDiagonal'_eq_blockDiagonal (M : o → Matrix m n α) {k k'} (i j) :
    blockDiagonal M (i, k) (j, k') = blockDiagonal' M ⟨k, i⟩ ⟨k', j⟩ 
goal: Matrix.blockDiagonal M (i, k) (j, k') = Matrix.blockDiagonal' M ⟨k, i⟩ ⟨k', j⟩

full_name: Matrix.blockDiagonal'_submatrix_eq_blockDiagonal
code: theorem blockDiagonal'_submatrix_eq_blockDiagonal (M : o → Matrix m n α) :
    (blockDiagonal' M).submatrix (Prod.toSigma ∘ Prod.swap) (Prod.toSigma ∘ Prod.swap) =
      blockDiagonal M 
goal: (Matrix.blockDiagonal' M).submatrix (Prod.toSigma ∘ Prod.swap) (Prod.toSigma ∘ Prod.swap) = Matrix.blockDiagonal M

full_name: Matrix.blockDiagonal'_apply
code: theorem blockDiagonal'_apply (M : ∀ i, Matrix (m' i) (n' i) α) (ik jk) :
    blockDiagonal' M ik jk =
      if h : ik.1 = jk.1 then M ik.1 ik.2 (cast (congr_arg n' h.symm) jk.2) else 0 
goal: Matrix.blockDiagonal' M ik jk = if h : ik.fst = jk.fst then M ik.fst ik.snd (cast ⋯ jk.snd) else 0

full_name: Matrix.blockDiagonal'_apply_eq
code: @[simp]
theorem blockDiagonal'_apply_eq (M : ∀ i, Matrix (m' i) (n' i) α) (k i j) :
    blockDiagonal' M ⟨k, i⟩ ⟨k, j⟩ = M k i j 
goal: Matrix.blockDiagonal' M ⟨k, i⟩ ⟨k, j⟩ = M k i j

full_name: Matrix.blockDiagonal'_apply_ne
code: theorem blockDiagonal'_apply_ne (M : ∀ i, Matrix (m' i) (n' i) α) {k k'} (i j) (h : k ≠ k') :
    blockDiagonal' M ⟨k, i⟩ ⟨k', j⟩ = 0 
goal: Matrix.blockDiagonal' M ⟨k, i⟩ ⟨k', j⟩ = 0

full_name: Matrix.blockDiagonal'_map
code: theorem blockDiagonal'_map (M : ∀ i, Matrix (m' i) (n' i) α) (f : α → β) (hf : f 0 = 0) :
    (blockDiagonal' M).map f = blockDiagonal' fun k => (M k).map f 
goal: (Matrix.blockDiagonal' M).map f = Matrix.blockDiagonal' fun k => (M k).map f

full_name: Matrix.blockDiagonal'_transpose
code: @[simp]
theorem blockDiagonal'_transpose (M : ∀ i, Matrix (m' i) (n' i) α) :
    (blockDiagonal' M)ᵀ = blockDiagonal' fun k => (M k)ᵀ 
goal: (Matrix.blockDiagonal' M)ᵀ = Matrix.blockDiagonal' fun k => (M k)ᵀ

full_name: Matrix.blockDiagonal'_conjTranspose
code: @[simp]
theorem blockDiagonal'_conjTranspose {α} [AddMonoid α] [StarAddMonoid α]
    (M : ∀ i, Matrix (m' i) (n' i) α) : (blockDiagonal' M)ᴴ = blockDiagonal' fun k => (M k)ᴴ 
goal: (Matrix.blockDiagonal' M)ᴴ = Matrix.blockDiagonal' fun k => (M k)ᴴ

full_name: Matrix.blockDiagonal'_zero
code: @[simp]
theorem blockDiagonal'_zero : blockDiagonal' (0 : ∀ i, Matrix (m' i) (n' i) α) = 0 
goal: Matrix.blockDiagonal' 0 = 0

full_name: Matrix.blockDiagonal'_diagonal
code: @[simp]
theorem blockDiagonal'_diagonal [∀ i, DecidableEq (m' i)] (d : ∀ i, m' i → α) :
    (blockDiagonal' fun k => diagonal (d k)) = diagonal fun ik => d ik.1 ik.2 
goal: (Matrix.blockDiagonal' fun k => Matrix.diagonal (d k)) = Matrix.diagonal fun ik => d ik.fst ik.snd

full_name: Matrix.blockDiagonal'_one
code: @[simp]
theorem blockDiagonal'_one [∀ i, DecidableEq (m' i)] [One α] :
    blockDiagonal' (1 : ∀ i, Matrix (m' i) (m' i) α) = 1 
goal: Matrix.blockDiagonal' 1 = 1

full_name: Matrix.blockDiagonal'_add
code: @[simp]
theorem blockDiagonal'_add [AddZeroClass α] (M N : ∀ i, Matrix (m' i) (n' i) α) :
    blockDiagonal' (M + N) = blockDiagonal' M + blockDiagonal' N 
goal: Matrix.blockDiagonal' (M + N) = Matrix.blockDiagonal' M + Matrix.blockDiagonal' N

full_name: Matrix.blockDiagonal'AddMonoidHom_apply
code: /-- `Matrix.blockDiagonal'` as an `AddMonoidHom`. -/
@[simps]
def blockDiagonal'AddMonoidHom [AddZeroClass α] :
    (∀ i, Matrix (m' i) (n' i) α) →+ Matrix (Σi, m' i) (Σi, n' i) α 
goal: (Matrix.blockDiagonal'AddMonoidHom m' n' α) M = Matrix.blockDiagonal' M

full_name: Matrix.blockDiagonal'AddMonoidHom
code: /-- `Matrix.blockDiagonal'` as an `AddMonoidHom`. -/
@[simps]
def blockDiagonal'AddMonoidHom [AddZeroClass α] :
    (∀ i, Matrix (m' i) (n' i) α) →+ Matrix (Σi, m' i) (Σi, n' i) α 
goal: ((i : o) → Matrix (m' i) (n' i) α) →+ Matrix ((i : o) × m' i) ((i : o) × n' i) α

full_name: Matrix.blockDiagonal'_neg
code: @[simp]
theorem blockDiagonal'_neg [AddGroup α] (M : ∀ i, Matrix (m' i) (n' i) α) :
    blockDiagonal' (-M) = -blockDiagonal' M 
goal: Matrix.blockDiagonal' (-M) = -Matrix.blockDiagonal' M

full_name: Matrix.blockDiagonal'_sub
code: @[simp]
theorem blockDiagonal'_sub [AddGroup α] (M N : ∀ i, Matrix (m' i) (n' i) α) :
    blockDiagonal' (M - N) = blockDiagonal' M - blockDiagonal' N 
goal: Matrix.blockDiagonal' (M - N) = Matrix.blockDiagonal' M - Matrix.blockDiagonal' N

full_name: Matrix.blockDiagonal'_mul
code: @[simp]
theorem blockDiagonal'_mul [NonUnitalNonAssocSemiring α] [∀ i, Fintype (n' i)] [Fintype o]
    (M : ∀ i, Matrix (m' i) (n' i) α) (N : ∀ i, Matrix (n' i) (p' i) α) :
    (blockDiagonal' fun k => M k * N k) = blockDiagonal' M * blockDiagonal' N 
goal: (Matrix.blockDiagonal' fun k => M k * N k) = Matrix.blockDiagonal' M * Matrix.blockDiagonal' N

full_name: Matrix.blockDiagonal'RingHom_apply
code: /-- `Matrix.blockDiagonal'` as a `RingHom`. -/
@[simps]
def blockDiagonal'RingHom [∀ i, DecidableEq (m' i)] [Fintype o] [∀ i, Fintype (m' i)]
    [NonAssocSemiring α] : (∀ i, Matrix (m' i) (m' i) α) →+* Matrix (Σi, m' i) (Σi, m' i) α 
goal: (Matrix.blockDiagonal'RingHom m' α) M = Matrix.blockDiagonal' M

full_name: Matrix.blockDiagonal'RingHom
code: /-- `Matrix.blockDiagonal'` as a `RingHom`. -/
@[simps]
def blockDiagonal'RingHom [∀ i, DecidableEq (m' i)] [Fintype o] [∀ i, Fintype (m' i)]
    [NonAssocSemiring α] : (∀ i, Matrix (m' i) (m' i) α) →+* Matrix (Σi, m' i) (Σi, m' i) α 
goal: ((i : o) → Matrix (m' i) (m' i) α) →+* Matrix ((i : o) × m' i) ((i : o) × m' i) α

full_name: Matrix.blockDiagonal'_pow
code: @[simp]
theorem blockDiagonal'_pow [∀ i, DecidableEq (m' i)] [Fintype o] [∀ i, Fintype (m' i)] [Semiring α]
    (M : ∀ i, Matrix (m' i) (m' i) α) (n : ℕ) : blockDiagonal' (M ^ n) = blockDiagonal' M ^ n 
goal: Matrix.blockDiagonal' (M ^ n) = Matrix.blockDiagonal' M ^ n

full_name: Matrix.blockDiagonal'_smul
code: @[simp]
theorem blockDiagonal'_smul {R : Type*} [Semiring R] [AddCommMonoid α] [Module R α] (x : R)
    (M : ∀ i, Matrix (m' i) (n' i) α) : blockDiagonal' (x • M) = x • blockDiagonal' M 
goal: Matrix.blockDiagonal' (x • M) = x • Matrix.blockDiagonal' M

full_name: Matrix.blockDiag'
code: /-- Extract a block from the diagonal of a block diagonal matrix.

This is the block form of `Matrix.diag`, and the left-inverse of `Matrix.blockDiagonal'`. -/
def blockDiag' (M : Matrix (Σi, m' i) (Σi, n' i) α) (k : o) : Matrix (m' k) (n' k) α 
goal: Matrix (m' k) (n' k) α

full_name: Matrix.blockDiag'_apply
code: theorem blockDiag'_apply (M : Matrix (Σi, m' i) (Σi, n' i) α) (k : o) (i j) :
    blockDiag' M k i j = M ⟨k, i⟩ ⟨k, j⟩ 
goal: M.blockDiag' k i j = M ⟨k, i⟩ ⟨k, j⟩

full_name: Matrix.blockDiag'_map
code: theorem blockDiag'_map (M : Matrix (Σi, m' i) (Σi, n' i) α) (f : α → β) :
    blockDiag' (M.map f) = fun k => (blockDiag' M k).map f 
goal: (M.map f).blockDiag' = fun k => (M.blockDiag' k).map f

full_name: Matrix.blockDiag'_transpose
code: @[simp]
theorem blockDiag'_transpose (M : Matrix (Σi, m' i) (Σi, n' i) α) (k : o) :
    blockDiag' Mᵀ k = (blockDiag' M k)ᵀ 
goal: Mᵀ.blockDiag' k = (M.blockDiag' k)ᵀ

full_name: Matrix.blockDiag'_conjTranspose
code: @[simp]
theorem blockDiag'_conjTranspose {α : Type*} [AddMonoid α] [StarAddMonoid α]
    (M : Matrix (Σi, m' i) (Σi, n' i) α) (k : o) : blockDiag' Mᴴ k = (blockDiag' M k)ᴴ 
goal: Mᴴ.blockDiag' k = (M.blockDiag' k)ᴴ

full_name: Matrix.blockDiag'_zero
code: @[simp]
theorem blockDiag'_zero : blockDiag' (0 : Matrix (Σi, m' i) (Σi, n' i) α) = 0 
goal: Matrix.blockDiag' 0 = 0

full_name: Matrix.blockDiag'_diagonal
code: @[simp]
theorem blockDiag'_diagonal [DecidableEq o] [∀ i, DecidableEq (m' i)] (d : (Σi, m' i) → α) (k : o) :
    blockDiag' (diagonal d) k = diagonal fun i => d ⟨k, i⟩ 
goal: (Matrix.diagonal d).blockDiag' k = Matrix.diagonal fun i => d ⟨k, i⟩

full_name: Matrix.blockDiag'_blockDiagonal'
code: @[simp]
theorem blockDiag'_blockDiagonal' [DecidableEq o] (M : ∀ i, Matrix (m' i) (n' i) α) :
    blockDiag' (blockDiagonal' M) = M 
goal: (Matrix.blockDiagonal' M).blockDiag' = M

full_name: Matrix.blockDiagonal'_injective
code: theorem blockDiagonal'_injective [DecidableEq o] :
    Function.Injective (blockDiagonal' : (∀ i, Matrix (m' i) (n' i) α) → Matrix _ _ α) 
goal: Function.Injective Matrix.blockDiagonal'

full_name: Matrix.blockDiagonal'_inj
code: @[simp]
theorem blockDiagonal'_inj [DecidableEq o] {M N : ∀ i, Matrix (m' i) (n' i) α} :
    blockDiagonal' M = blockDiagonal' N ↔ M = N 
goal: Matrix.blockDiagonal' M = Matrix.blockDiagonal' N ↔ M = N

full_name: Matrix.blockDiag'_one
code: @[simp]
theorem blockDiag'_one [DecidableEq o] [∀ i, DecidableEq (m' i)] [One α] :
    blockDiag' (1 : Matrix (Σi, m' i) (Σi, m' i) α) = 1 
goal: Matrix.blockDiag' 1 = 1

full_name: Matrix.blockDiag'_add
code: @[simp]
theorem blockDiag'_add [AddZeroClass α] (M N : Matrix (Σi, m' i) (Σi, n' i) α) :
    blockDiag' (M + N) = blockDiag' M + blockDiag' N 
goal: (M + N).blockDiag' = M.blockDiag' + N.blockDiag'

full_name: Matrix.blockDiag'AddMonoidHom_apply
code: /-- `Matrix.blockDiag'` as an `AddMonoidHom`. -/
@[simps]
def blockDiag'AddMonoidHom [AddZeroClass α] :
    Matrix (Σi, m' i) (Σi, n' i) α →+ ∀ i, Matrix (m' i) (n' i) α 
goal: (Matrix.blockDiag'AddMonoidHom m' n' α) M k = M.blockDiag' k

full_name: Matrix.blockDiag'AddMonoidHom
code: /-- `Matrix.blockDiag'` as an `AddMonoidHom`. -/
@[simps]
def blockDiag'AddMonoidHom [AddZeroClass α] :
    Matrix (Σi, m' i) (Σi, n' i) α →+ ∀ i, Matrix (m' i) (n' i) α 
goal: Matrix ((i : o) × m' i) ((i : o) × n' i) α →+ (i : o) → Matrix (m' i) (n' i) α

full_name: Matrix.blockDiag'_neg
code: @[simp]
theorem blockDiag'_neg [AddGroup α] (M : Matrix (Σi, m' i) (Σi, n' i) α) :
    blockDiag' (-M) = -blockDiag' M 
goal: (-M).blockDiag' = -M.blockDiag'

full_name: Matrix.blockDiag'_sub
code: @[simp]
theorem blockDiag'_sub [AddGroup α] (M N : Matrix (Σi, m' i) (Σi, n' i) α) :
    blockDiag' (M - N) = blockDiag' M - blockDiag' N 
goal: (M - N).blockDiag' = M.blockDiag' - N.blockDiag'

full_name: Matrix.blockDiag'_smul
code: @[simp]
theorem blockDiag'_smul {R : Type*} [Monoid R] [AddMonoid α] [DistribMulAction R α] (x : R)
    (M : Matrix (Σi, m' i) (Σi, n' i) α) : blockDiag' (x • M) = x • blockDiag' M 
goal: (x • M).blockDiag' = x • M.blockDiag'

full_name: Matrix.toBlock_mul_eq_mul
code: theorem toBlock_mul_eq_mul {m n k : Type*} [Fintype n] (p : m → Prop) (q : k → Prop)
    (A : Matrix m n R) (B : Matrix n k R) :
    (A * B).toBlock p q = A.toBlock p ⊤ * B.toBlock ⊤ q 
goal: (A * B).toBlock p q = A.toBlock p ⊤ * B.toBlock ⊤ q

full_name: Matrix.toBlock_mul_eq_add
code: theorem toBlock_mul_eq_add {m n k : Type*} [Fintype n] (p : m → Prop) (q : n → Prop)
    [DecidablePred q] (r : k → Prop) (A : Matrix m n R) (B : Matrix n k R) : (A * B).toBlock p r =
    A.toBlock p q * B.toBlock q r + (A.toBlock p fun i => ¬q i) * B.toBlock (fun i => ¬q i) r 
goal: (A * B).toBlock p r = A.toBlock p q * B.toBlock q r + (A.toBlock p fun i => ¬q i) * B.toBlock (fun i => ¬q i) r