File: Mathlib/Data/Matrix/Kronecker.lean

full_name: Matrix.kroneckerMap
code: /-- Produce a matrix with `f` applied to every pair of elements from `A` and `B`. -/
def kroneckerMap (f : α → β → γ) (A : Matrix l m α) (B : Matrix n p β) : Matrix (l × n) (m × p) γ 
goal: Matrix (l × n) (m × p) γ

full_name: Matrix.kroneckerMap_apply
code: @[simp]
theorem kroneckerMap_apply (f : α → β → γ) (A : Matrix l m α) (B : Matrix n p β) (i j) :
    kroneckerMap f A B i j = f (A i.1 j.1) (B i.2 j.2) 
goal: Matrix.kroneckerMap f A B i j = f (A i.1 j.1) (B i.2 j.2)

full_name: Matrix.kroneckerMap_transpose
code: theorem kroneckerMap_transpose (f : α → β → γ) (A : Matrix l m α) (B : Matrix n p β) :
    kroneckerMap f Aᵀ Bᵀ = (kroneckerMap f A B)ᵀ 
goal: Matrix.kroneckerMap f A.transpose B.transpose = (Matrix.kroneckerMap f A B).transpose

full_name: Matrix.kroneckerMap_map_left
code: theorem kroneckerMap_map_left (f : α' → β → γ) (g : α → α') (A : Matrix l m α) (B : Matrix n p β) :
    kroneckerMap f (A.map g) B = kroneckerMap (fun a b => f (g a) b) A B 
goal: Matrix.kroneckerMap f (A.map g) B = Matrix.kroneckerMap (fun a b => f (g a) b) A B

full_name: Matrix.kroneckerMap_map_right
code: theorem kroneckerMap_map_right (f : α → β' → γ) (g : β → β') (A : Matrix l m α) (B : Matrix n p β) :
    kroneckerMap f A (B.map g) = kroneckerMap (fun a b => f a (g b)) A B 
goal: Matrix.kroneckerMap f A (B.map g) = Matrix.kroneckerMap (fun a b => f a (g b)) A B

full_name: Matrix.kroneckerMap_map
code: theorem kroneckerMap_map (f : α → β → γ) (g : γ → γ') (A : Matrix l m α) (B : Matrix n p β) :
    (kroneckerMap f A B).map g = kroneckerMap (fun a b => g (f a b)) A B 
goal: (Matrix.kroneckerMap f A B).map g = Matrix.kroneckerMap (fun a b => g (f a b)) A B

full_name: Matrix.kroneckerMap_zero_left
code: @[simp]
theorem kroneckerMap_zero_left [Zero α] [Zero γ] (f : α → β → γ) (hf : ∀ b, f 0 b = 0)
    (B : Matrix n p β) : kroneckerMap f (0 : Matrix l m α) B = 0 
goal: Matrix.kroneckerMap f 0 B = 0

full_name: Matrix.kroneckerMap_zero_right
code: @[simp]
theorem kroneckerMap_zero_right [Zero β] [Zero γ] (f : α → β → γ) (hf : ∀ a, f a 0 = 0)
    (A : Matrix l m α) : kroneckerMap f A (0 : Matrix n p β) = 0 
goal: Matrix.kroneckerMap f A 0 = 0

full_name: Matrix.kroneckerMap_add_left
code: theorem kroneckerMap_add_left [Add α] [Add γ] (f : α → β → γ)
    (hf : ∀ a₁ a₂ b, f (a₁ + a₂) b = f a₁ b + f a₂ b) (A₁ A₂ : Matrix l m α) (B : Matrix n p β) :
    kroneckerMap f (A₁ + A₂) B = kroneckerMap f A₁ B + kroneckerMap f A₂ B 
goal: Matrix.kroneckerMap f (A₁ + A₂) B = Matrix.kroneckerMap f A₁ B + Matrix.kroneckerMap f A₂ B

full_name: Matrix.kroneckerMap_add_right
code: theorem kroneckerMap_add_right [Add β] [Add γ] (f : α → β → γ)
    (hf : ∀ a b₁ b₂, f a (b₁ + b₂) = f a b₁ + f a b₂) (A : Matrix l m α) (B₁ B₂ : Matrix n p β) :
    kroneckerMap f A (B₁ + B₂) = kroneckerMap f A B₁ + kroneckerMap f A B₂ 
goal: Matrix.kroneckerMap f A (B₁ + B₂) = Matrix.kroneckerMap f A B₁ + Matrix.kroneckerMap f A B₂

full_name: Matrix.kroneckerMap_smul_left
code: theorem kroneckerMap_smul_left [SMul R α] [SMul R γ] (f : α → β → γ) (r : R)
    (hf : ∀ a b, f (r • a) b = r • f a b) (A : Matrix l m α) (B : Matrix n p β) :
    kroneckerMap f (r • A) B = r • kroneckerMap f A B 
goal: Matrix.kroneckerMap f (r • A) B = r • Matrix.kroneckerMap f A B

full_name: Matrix.kroneckerMap_smul_right
code: theorem kroneckerMap_smul_right [SMul R β] [SMul R γ] (f : α → β → γ) (r : R)
    (hf : ∀ a b, f a (r • b) = r • f a b) (A : Matrix l m α) (B : Matrix n p β) :
    kroneckerMap f A (r • B) = r • kroneckerMap f A B 
goal: Matrix.kroneckerMap f A (r • B) = r • Matrix.kroneckerMap f A B

full_name: Matrix.kroneckerMap_diagonal_diagonal
code: theorem kroneckerMap_diagonal_diagonal [Zero α] [Zero β] [Zero γ] [DecidableEq m] [DecidableEq n]
    (f : α → β → γ) (hf₁ : ∀ b, f 0 b = 0) (hf₂ : ∀ a, f a 0 = 0) (a : m → α) (b : n → β) :
    kroneckerMap f (diagonal a) (diagonal b) = diagonal fun mn => f (a mn.1) (b mn.2) 
goal: Matrix.kroneckerMap f (Matrix.diagonal a) (Matrix.diagonal b) = Matrix.diagonal fun mn => f (a mn.1) (b mn.2)

full_name: Matrix.kroneckerMap_diagonal_right
code: theorem kroneckerMap_diagonal_right [Zero β] [Zero γ] [DecidableEq n] (f : α → β → γ)
    (hf : ∀ a, f a 0 = 0) (A : Matrix l m α) (b : n → β) :
    kroneckerMap f A (diagonal b) = blockDiagonal fun i => A.map fun a => f a (b i) 
goal: Matrix.kroneckerMap f A (Matrix.diagonal b) = Matrix.blockDiagonal fun i => A.map fun a => f a (b i)

full_name: Matrix.kroneckerMap_diagonal_left
code: theorem kroneckerMap_diagonal_left [Zero α] [Zero γ] [DecidableEq l] (f : α → β → γ)
    (hf : ∀ b, f 0 b = 0) (a : l → α) (B : Matrix m n β) :
    kroneckerMap f (diagonal a) B =
      Matrix.reindex (Equiv.prodComm _ _) (Equiv.prodComm _ _)
        (blockDiagonal fun i => B.map fun b => f (a i) b) 
goal: Matrix.kroneckerMap f (Matrix.diagonal a) B =
  (Matrix.reindex (Equiv.prodComm m l) (Equiv.prodComm n l)) (Matrix.blockDiagonal fun i => B.map fun b => f (a i) b)

full_name: Matrix.kroneckerMap_one_one
code: @[simp]
theorem kroneckerMap_one_one [Zero α] [Zero β] [Zero γ] [One α] [One β] [One γ] [DecidableEq m]
    [DecidableEq n] (f : α → β → γ) (hf₁ : ∀ b, f 0 b = 0) (hf₂ : ∀ a, f a 0 = 0)
    (hf₃ : f 1 1 = 1) : kroneckerMap f (1 : Matrix m m α) (1 : Matrix n n β) = 1 
goal: Matrix.kroneckerMap f 1 1 = 1

full_name: Matrix.kroneckerMap_reindex
code: theorem kroneckerMap_reindex (f : α → β → γ) (el : l ≃ l') (em : m ≃ m') (en : n ≃ n') (ep : p ≃ p')
    (M : Matrix l m α) (N : Matrix n p β) :
    kroneckerMap f (reindex el em M) (reindex en ep N) =
      reindex (el.prodCongr en) (em.prodCongr ep) (kroneckerMap f M N) 
goal: Matrix.kroneckerMap f ((Matrix.reindex el em) M) ((Matrix.reindex en ep) N) =
  (Matrix.reindex (el.prodCongr en) (em.prodCongr ep)) (Matrix.kroneckerMap f M N)

full_name: Matrix.kroneckerMap_reindex_left
code: theorem kroneckerMap_reindex_left (f : α → β → γ) (el : l ≃ l') (em : m ≃ m') (M : Matrix l m α)
    (N : Matrix n n' β) :
    kroneckerMap f (Matrix.reindex el em M) N =
      reindex (el.prodCongr (Equiv.refl _)) (em.prodCongr (Equiv.refl _)) (kroneckerMap f M N) 
goal: Matrix.kroneckerMap f ((Matrix.reindex el em) M) N =
  (Matrix.reindex (el.prodCongr (Equiv.refl n)) (em.prodCongr (Equiv.refl n'))) (Matrix.kroneckerMap f M N)

full_name: Matrix.kroneckerMap_reindex_right
code: theorem kroneckerMap_reindex_right (f : α → β → γ) (em : m ≃ m') (en : n ≃ n') (M : Matrix l l' α)
    (N : Matrix m n β) :
    kroneckerMap f M (reindex em en N) =
      reindex ((Equiv.refl _).prodCongr em) ((Equiv.refl _).prodCongr en) (kroneckerMap f M N) 
goal: Matrix.kroneckerMap f M ((Matrix.reindex em en) N) =
  (Matrix.reindex ((Equiv.refl l).prodCongr em) ((Equiv.refl l').prodCongr en)) (Matrix.kroneckerMap f M N)

full_name: Matrix.kroneckerMap_assoc
code: theorem kroneckerMap_assoc {δ ξ ω ω' : Type*} (f : α → β → γ) (g : γ → δ → ω) (f' : α → ξ → ω')
    (g' : β → δ → ξ) (A : Matrix l m α) (B : Matrix n p β) (D : Matrix q r δ) (φ : ω ≃ ω')
    (hφ : ∀ a b d, φ (g (f a b) d) = f' a (g' b d)) :
    (reindex (Equiv.prodAssoc l n q) (Equiv.prodAssoc m p r)).trans (Equiv.mapMatrix φ)
        (kroneckerMap g (kroneckerMap f A B) D) =
      kroneckerMap f' A (kroneckerMap g' B D) 
goal: ((Matrix.reindex (Equiv.prodAssoc l n q) (Equiv.prodAssoc m p r)).trans φ.mapMatrix)
    (Matrix.kroneckerMap g (Matrix.kroneckerMap f A B) D) =
  Matrix.kroneckerMap f' A (Matrix.kroneckerMap g' B D)

full_name: Matrix.kroneckerMap_assoc₁
code: theorem kroneckerMap_assoc₁ {δ ξ ω : Type*} (f : α → β → γ) (g : γ → δ → ω) (f' : α → ξ → ω)
    (g' : β → δ → ξ) (A : Matrix l m α) (B : Matrix n p β) (D : Matrix q r δ)
    (h : ∀ a b d, g (f a b) d = f' a (g' b d)) :
    reindex (Equiv.prodAssoc l n q) (Equiv.prodAssoc m p r)
        (kroneckerMap g (kroneckerMap f A B) D) =
      kroneckerMap f' A (kroneckerMap g' B D) 
goal: (Matrix.reindex (Equiv.prodAssoc l n q) (Equiv.prodAssoc m p r)) (Matrix.kroneckerMap g (Matrix.kroneckerMap f A B) D) =
  Matrix.kroneckerMap f' A (Matrix.kroneckerMap g' B D)

full_name: Matrix.kroneckerMapBilinear_apply_apply
code: /-- When `f` is bilinear then `Matrix.kroneckerMap f` is also bilinear. -/
@[simps!]
def kroneckerMapBilinear [CommSemiring R] [AddCommMonoid α] [AddCommMonoid β] [AddCommMonoid γ]
    [Module R α] [Module R β] [Module R γ] (f : α →ₗ[R] β →ₗ[R] γ) :
    Matrix l m α →ₗ[R] Matrix n p β →ₗ[R] Matrix (l × n) (m × p) γ 
goal: ∀ (m_1 : Matrix l m α) (B : Matrix n p β),
  ((Matrix.kroneckerMapBilinear f) m_1) B = Matrix.kroneckerMap (fun r s => (f r) s) m_1 B

full_name: Matrix.kroneckerMapBilinear
code: /-- When `f` is bilinear then `Matrix.kroneckerMap f` is also bilinear. -/
@[simps!]
def kroneckerMapBilinear [CommSemiring R] [AddCommMonoid α] [AddCommMonoid β] [AddCommMonoid γ]
    [Module R α] [Module R β] [Module R γ] (f : α →ₗ[R] β →ₗ[R] γ) :
    Matrix l m α →ₗ[R] Matrix n p β →ₗ[R] Matrix (l × n) (m × p) γ 
goal: Matrix l m α →ₗ[R] Matrix n p β →ₗ[R] Matrix (l × n) (m × p) γ

full_name: Matrix.kroneckerMapBilinear_mul_mul
code: /-- `Matrix.kroneckerMapBilinear` commutes with `*` if `f` does.

This is primarily used with `R = ℕ` to prove `Matrix.mul_kronecker_mul`. -/
theorem kroneckerMapBilinear_mul_mul [CommSemiring R] [Fintype m] [Fintype m']
    [NonUnitalNonAssocSemiring α] [NonUnitalNonAssocSemiring β] [NonUnitalNonAssocSemiring γ]
    [Module R α] [Module R β] [Module R γ] (f : α →ₗ[R] β →ₗ[R] γ)
    (h_comm : ∀ a b a' b', f (a * b) (a' * b') = f a a' * f b b') (A : Matrix l m α)
    (B : Matrix m n α) (A' : Matrix l' m' β) (B' : Matrix m' n' β) :
    kroneckerMapBilinear f (A * B) (A' * B') =
      kroneckerMapBilinear f A A' * kroneckerMapBilinear f B B' 
goal: ((Matrix.kroneckerMapBilinear f) (A * B)) (A' * B') =
  ((Matrix.kroneckerMapBilinear f) A) A' * ((Matrix.kroneckerMapBilinear f) B) B'

full_name: Matrix.trace_kroneckerMapBilinear
code: /-- `trace` distributes over `Matrix.kroneckerMapBilinear`.

This is primarily used with `R = ℕ` to prove `Matrix.trace_kronecker`. -/
theorem trace_kroneckerMapBilinear [CommSemiring R] [Fintype m] [Fintype n] [AddCommMonoid α]
    [AddCommMonoid β] [AddCommMonoid γ] [Module R α] [Module R β] [Module R γ]
    (f : α →ₗ[R] β →ₗ[R] γ) (A : Matrix m m α) (B : Matrix n n β) :
    trace (kroneckerMapBilinear f A B) = f (trace A) (trace B) 
goal: (((Matrix.kroneckerMapBilinear f) A) B).trace = (f A.trace) B.trace

full_name: Matrix.det_kroneckerMapBilinear
code: /-- `determinant` of `Matrix.kroneckerMapBilinear`.

This is primarily used with `R = ℕ` to prove `Matrix.det_kronecker`. -/
theorem det_kroneckerMapBilinear [CommSemiring R] [Fintype m] [Fintype n] [DecidableEq m]
    [DecidableEq n] [CommRing α] [CommRing β] [CommRing γ] [Module R α] [Module R β] [Module R γ]
    (f : α →ₗ[R] β →ₗ[R] γ) (h_comm : ∀ a b a' b', f (a * b) (a' * b') = f a a' * f b b')
    (A : Matrix m m α) (B : Matrix n n β) :
    det (kroneckerMapBilinear f A B) =
      det (A.map fun a => f a 1) ^ Fintype.card n * det (B.map fun b => f 1 b) ^ Fintype.card m 
goal: (((Matrix.kroneckerMapBilinear f) A) B).det =
  (A.map fun a => (f a) 1).det ^ Fintype.card n * (B.map fun b => (f 1) b).det ^ Fintype.card m

full_name: Matrix.kronecker
code: /-- The Kronecker product. This is just a shorthand for `kroneckerMap (*)`. Prefer the notation
`⊗ₖ` rather than this definition. -/
@[simp]
def kronecker [Mul α] : Matrix l m α → Matrix n p α → Matrix (l × n) (m × p) α 
goal: Matrix l m α → Matrix n p α → Matrix (l × n) (m × p) α

full_name: Kronecker.«_aux_Mathlib_Data_Matrix_Kronecker___macroRules_Kronecker_term_⊗ₖ__1»
code: scoped[Kronecker] infixl:100 " ⊗ₖ " => Matrix.kroneckerMap (· * ·)
goal: Lean.Macro

full_name: Matrix.kronecker_apply
code: @[simp]
theorem kronecker_apply [Mul α] (A : Matrix l m α) (B : Matrix n p α) (i₁ i₂ j₁ j₂) :
    (A ⊗ₖ B) (i₁, i₂) (j₁, j₂) = A i₁ j₁ * B i₂ j₂ 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) A B (i₁, i₂) (j₁, j₂) = A i₁ j₁ * B i₂ j₂

full_name: Matrix.kroneckerBilinear
code: /-- `Matrix.kronecker` as a bilinear map. -/
def kroneckerBilinear [CommSemiring R] [Semiring α] [Algebra R α] :
    Matrix l m α →ₗ[R] Matrix n p α →ₗ[R] Matrix (l × n) (m × p) α 
goal: Matrix l m α →ₗ[R] Matrix n p α →ₗ[R] Matrix (l × n) (m × p) α

full_name: Matrix.zero_kronecker
code: theorem zero_kronecker [MulZeroClass α] (B : Matrix n p α) : (0 : Matrix l m α) ⊗ₖ B = 0 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) 0 B = 0

full_name: Matrix.kronecker_zero
code: theorem kronecker_zero [MulZeroClass α] (A : Matrix l m α) : A ⊗ₖ (0 : Matrix n p α) = 0 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) A 0 = 0

full_name: Matrix.add_kronecker
code: theorem add_kronecker [Distrib α] (A₁ A₂ : Matrix l m α) (B : Matrix n p α) :
    (A₁ + A₂) ⊗ₖ B = A₁ ⊗ₖ B + A₂ ⊗ₖ B 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) (A₁ + A₂) B =
  Matrix.kroneckerMap (fun x x_1 => x * x_1) A₁ B + Matrix.kroneckerMap (fun x x_1 => x * x_1) A₂ B

full_name: Matrix.kronecker_add
code: theorem kronecker_add [Distrib α] (A : Matrix l m α) (B₁ B₂ : Matrix n p α) :
    A ⊗ₖ (B₁ + B₂) = A ⊗ₖ B₁ + A ⊗ₖ B₂ 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) A (B₁ + B₂) =
  Matrix.kroneckerMap (fun x x_1 => x * x_1) A B₁ + Matrix.kroneckerMap (fun x x_1 => x * x_1) A B₂

full_name: Matrix.smul_kronecker
code: theorem smul_kronecker [Monoid R] [Monoid α] [MulAction R α] [IsScalarTower R α α] (r : R)
    (A : Matrix l m α) (B : Matrix n p α) : (r • A) ⊗ₖ B = r • A ⊗ₖ B 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) (r • A) B = r • Matrix.kroneckerMap (fun x x_1 => x * x_1) A B

full_name: Matrix.kronecker_smul
code: theorem kronecker_smul [Monoid R] [Monoid α] [MulAction R α] [SMulCommClass R α α] (r : R)
    (A : Matrix l m α) (B : Matrix n p α) : A ⊗ₖ (r • B) = r • A ⊗ₖ B 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) A (r • B) = r • Matrix.kroneckerMap (fun x x_1 => x * x_1) A B

full_name: Matrix.diagonal_kronecker_diagonal
code: theorem diagonal_kronecker_diagonal [MulZeroClass α] [DecidableEq m] [DecidableEq n] (a : m → α)
    (b : n → α) : diagonal a ⊗ₖ diagonal b = diagonal fun mn => a mn.1 * b mn.2 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) (Matrix.diagonal a) (Matrix.diagonal b) =
  Matrix.diagonal fun mn => a mn.1 * b mn.2

full_name: Matrix.kronecker_diagonal
code: theorem kronecker_diagonal [MulZeroClass α] [DecidableEq n] (A : Matrix l m α) (b : n → α) :
    A ⊗ₖ diagonal b = blockDiagonal fun i => A <• b i 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) A (Matrix.diagonal b) =
  Matrix.blockDiagonal fun i => MulOpposite.op (b i) • A

full_name: Matrix.diagonal_kronecker
code: theorem diagonal_kronecker [MulZeroClass α] [DecidableEq l] (a : l → α) (B : Matrix m n α) :
    diagonal a ⊗ₖ B =
      Matrix.reindex (Equiv.prodComm _ _) (Equiv.prodComm _ _) (blockDiagonal fun i => a i • B) 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) (Matrix.diagonal a) B =
  (Matrix.reindex (Equiv.prodComm m l) (Equiv.prodComm n l)) (Matrix.blockDiagonal fun i => a i • B)

full_name: Matrix.natCast_kronecker_natCast
code: @[simp]
theorem natCast_kronecker_natCast [NonAssocSemiring α] [DecidableEq m] [DecidableEq n] (a b : ℕ) :
    (a : Matrix m m α) ⊗ₖ (b : Matrix n n α) = ↑(a * b) 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) ↑a ↑b = ↑(a * b)

full_name: Matrix.kronecker_natCast
code: theorem kronecker_natCast [NonAssocSemiring α] [DecidableEq n] (A : Matrix l m α) (b : ℕ) :
    A ⊗ₖ (b : Matrix n n α) = blockDiagonal fun _ => b • A 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) A ↑b = Matrix.blockDiagonal fun x => b • A

full_name: Matrix.natCast_kronecker
code: theorem natCast_kronecker [NonAssocSemiring α] [DecidableEq l] (a : ℕ) (B : Matrix m n α) :
    (a : Matrix l l α) ⊗ₖ B =
      Matrix.reindex (Equiv.prodComm _ _) (Equiv.prodComm _ _) (blockDiagonal fun _ => a • B) 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) (↑a) B =
  (Matrix.reindex (Equiv.prodComm m l) (Equiv.prodComm n l)) (Matrix.blockDiagonal fun x => a • B)

full_name: Matrix.kronecker_ofNat
code: theorem kronecker_ofNat [Semiring α] [DecidableEq n] (A : Matrix l m α) (b : ℕ) [b.AtLeastTwo] :
    A ⊗ₖ (no_index (OfNat.ofNat b) : Matrix n n α) =
      blockDiagonal fun _ => A <• (OfNat.ofNat b : α) 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) A (OfNat.ofNat b) =
  Matrix.blockDiagonal fun x => MulOpposite.op (OfNat.ofNat b) • A

full_name: Matrix.ofNat_kronecker
code: theorem ofNat_kronecker [Semiring α] [DecidableEq l] (a : ℕ) [a.AtLeastTwo] (B : Matrix m n α) :
    (no_index (OfNat.ofNat a) : Matrix l l α) ⊗ₖ B =
      Matrix.reindex (.prodComm _ _) (.prodComm _ _)
        (blockDiagonal fun _ => (OfNat.ofNat a : α) • B) 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) (OfNat.ofNat a) B =
  (Matrix.reindex (Equiv.prodComm m l) (Equiv.prodComm n l)) (Matrix.blockDiagonal fun x => OfNat.ofNat a • B)

full_name: Matrix.one_kronecker_one
code: theorem one_kronecker_one [MulZeroOneClass α] [DecidableEq m] [DecidableEq n] :
    (1 : Matrix m m α) ⊗ₖ (1 : Matrix n n α) = 1 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) 1 1 = 1

full_name: Matrix.kronecker_one
code: theorem kronecker_one [MulZeroOneClass α] [DecidableEq n] (A : Matrix l m α) :
    A ⊗ₖ (1 : Matrix n n α) = blockDiagonal fun _ => A 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) A 1 = Matrix.blockDiagonal fun x => A

full_name: Matrix.one_kronecker
code: theorem one_kronecker [MulZeroOneClass α] [DecidableEq l] (B : Matrix m n α) :
    (1 : Matrix l l α) ⊗ₖ B =
      Matrix.reindex (Equiv.prodComm _ _) (Equiv.prodComm _ _) (blockDiagonal fun _ => B) 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) 1 B =
  (Matrix.reindex (Equiv.prodComm m l) (Equiv.prodComm n l)) (Matrix.blockDiagonal fun x => B)

full_name: Matrix.mul_kronecker_mul
code: theorem mul_kronecker_mul [Fintype m] [Fintype m'] [CommSemiring α] (A : Matrix l m α)
    (B : Matrix m n α) (A' : Matrix l' m' α) (B' : Matrix m' n' α) :
    (A * B) ⊗ₖ (A' * B') = A ⊗ₖ A' * B ⊗ₖ B' 
goal: Matrix.kroneckerMap (fun x x_1 => x * x_1) (A * B) (A' * B') =
  Matrix.kroneckerMap (fun x x_1 => x * x_1) A A' * Matrix.kroneckerMap (fun x x_1 => x * x_1) B B'

full_name: Matrix.kronecker_assoc
code: theorem kronecker_assoc [Semigroup α] (A : Matrix l m α) (B : Matrix n p α) (C : Matrix q r α) :
    reindex (Equiv.prodAssoc l n q) (Equiv.prodAssoc m p r) (A ⊗ₖ B ⊗ₖ C) = A ⊗ₖ (B ⊗ₖ C) 
goal: (Matrix.reindex (Equiv.prodAssoc l n q) (Equiv.prodAssoc m p r))
    (Matrix.kroneckerMap (fun x x_1 => x * x_1) (Matrix.kroneckerMap (fun x x_1 => x * x_1) A B) C) =
  Matrix.kroneckerMap (fun x x_1 => x * x_1) A (Matrix.kroneckerMap (fun x x_1 => x * x_1) B C)

full_name: Matrix.kronecker_assoc'
code: @[simp]
theorem kronecker_assoc' [Semigroup α] (A : Matrix l m α) (B : Matrix n p α) (C : Matrix q r α) :
    submatrix (A ⊗ₖ B ⊗ₖ C) (Equiv.prodAssoc l n q).symm (Equiv.prodAssoc m p r).symm =
    A ⊗ₖ (B ⊗ₖ C) 
goal: (Matrix.kroneckerMap (fun x x_1 => x * x_1) (Matrix.kroneckerMap (fun x x_1 => x * x_1) A B) C).submatrix
    ⇑(Equiv.prodAssoc l n q).symm ⇑(Equiv.prodAssoc m p r).symm =
  Matrix.kroneckerMap (fun x x_1 => x * x_1) A (Matrix.kroneckerMap (fun x x_1 => x * x_1) B C)

full_name: Matrix.trace_kronecker
code: theorem trace_kronecker [Fintype m] [Fintype n] [Semiring α] (A : Matrix m m α) (B : Matrix n n α) :
    trace (A ⊗ₖ B) = trace A * trace B 
goal: (Matrix.kroneckerMap (fun x x_1 => x * x_1) A B).trace = A.trace * B.trace

full_name: Matrix.det_kronecker
code: theorem det_kronecker [Fintype m] [Fintype n] [DecidableEq m] [DecidableEq n] [CommRing R]
    (A : Matrix m m R) (B : Matrix n n R) :
    det (A ⊗ₖ B) = det A ^ Fintype.card n * det B ^ Fintype.card m 
goal: (Matrix.kroneckerMap (fun x x_1 => x * x_1) A B).det = A.det ^ Fintype.card n * B.det ^ Fintype.card m

full_name: Matrix.inv_kronecker
code: theorem inv_kronecker [Fintype m] [Fintype n] [DecidableEq m] [DecidableEq n] [CommRing R]
    (A : Matrix m m R) (B : Matrix n n R) : (A ⊗ₖ B)⁻¹ = A⁻¹ ⊗ₖ B⁻¹ 
goal: (Matrix.kroneckerMap (fun x x_1 => x * x_1) A B)⁻¹ = Matrix.kroneckerMap (fun x x_1 => x * x_1) A⁻¹ B⁻¹

full_name: Matrix.kroneckerTMul
code: /-- The Kronecker tensor product. This is just a shorthand for `kroneckerMap (⊗ₜ)`.
Prefer the notation `⊗ₖₜ` rather than this definition. -/
@[simp]
def kroneckerTMul : Matrix l m α → Matrix n p β → Matrix (l × n) (m × p) (α ⊗[R] β) 
goal: Matrix l m α → Matrix n p β → Matrix (l × n) (m × p) (TensorProduct R α β)

full_name: Kronecker.«_aux_Mathlib_Data_Matrix_Kronecker___macroRules_Kronecker_term_⊗ₖₜ__1»
code: scoped[Kronecker] infixl:100 " ⊗ₖₜ " => Matrix.kroneckerMap (· ⊗ₜ ·)
goal: Lean.Macro

full_name: Kronecker.«_aux_Mathlib_Data_Matrix_Kronecker___macroRules_Kronecker_term_⊗ₖₜ[_]__1»
code: scoped[Kronecker]
  notation:100 x " ⊗ₖₜ[" R "] " y:100 => Matrix.kroneckerMap (TensorProduct.tmul R) x y
goal: Lean.Macro

full_name: Kronecker._aux_Mathlib_Data_Matrix_Kronecker___unexpand_Matrix_kroneckerMap_1
code: scoped[Kronecker]
  notation:100 x " ⊗ₖₜ[" R "] " y:100 => Matrix.kroneckerMap (TensorProduct.tmul R) x y
goal: Lean.PrettyPrinter.Unexpander

full_name: Matrix.kroneckerTMul_apply
code: @[simp]
theorem kroneckerTMul_apply (A : Matrix l m α) (B : Matrix n p β) (i₁ i₂ j₁ j₂) :
    (A ⊗ₖₜ B) (i₁, i₂) (j₁, j₂) = A i₁ j₁ ⊗ₜ[R] B i₂ j₂ 
goal: Matrix.kroneckerMap (fun x x_1 => x ⊗ₜ[R] x_1) A B (i₁, i₂) (j₁, j₂) = A i₁ j₁ ⊗ₜ[R] B i₂ j₂

full_name: Matrix.kroneckerTMulBilinear
code: /-- `Matrix.kronecker` as a bilinear map. -/
def kroneckerTMulBilinear :
    Matrix l m α →ₗ[R] Matrix n p β →ₗ[R] Matrix (l × n) (m × p) (α ⊗[R] β) 
goal: Matrix l m α →ₗ[R] Matrix n p β →ₗ[R] Matrix (l × n) (m × p) (TensorProduct R α β)

full_name: Matrix.zero_kroneckerTMul
code: theorem zero_kroneckerTMul (B : Matrix n p β) : (0 : Matrix l m α) ⊗ₖₜ[R] B = 0 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) 0 B = 0

full_name: Matrix.kroneckerTMul_zero
code: theorem kroneckerTMul_zero (A : Matrix l m α) : A ⊗ₖₜ[R] (0 : Matrix n p β) = 0 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) A 0 = 0

full_name: Matrix.add_kroneckerTMul
code: theorem add_kroneckerTMul (A₁ A₂ : Matrix l m α) (B : Matrix n p α) :
    (A₁ + A₂) ⊗ₖₜ[R] B = A₁ ⊗ₖₜ B + A₂ ⊗ₖₜ B 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) (A₁ + A₂) B =
  Matrix.kroneckerMap (fun x x_1 => x ⊗ₜ[R] x_1) A₁ B + Matrix.kroneckerMap (fun x x_1 => x ⊗ₜ[R] x_1) A₂ B

full_name: Matrix.kroneckerTMul_add
code: theorem kroneckerTMul_add (A : Matrix l m α) (B₁ B₂ : Matrix n p α) :
    A ⊗ₖₜ[R] (B₁ + B₂) = A ⊗ₖₜ B₁ + A ⊗ₖₜ B₂ 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) A (B₁ + B₂) =
  Matrix.kroneckerMap (fun x x_1 => x ⊗ₜ[R] x_1) A B₁ + Matrix.kroneckerMap (fun x x_1 => x ⊗ₜ[R] x_1) A B₂

full_name: Matrix.smul_kroneckerTMul
code: theorem smul_kroneckerTMul (r : R) (A : Matrix l m α) (B : Matrix n p α) :
    (r • A) ⊗ₖₜ[R] B = r • A ⊗ₖₜ B 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) (r • A) B = r • Matrix.kroneckerMap (fun x x_1 => x ⊗ₜ[R] x_1) A B

full_name: Matrix.kroneckerTMul_smul
code: theorem kroneckerTMul_smul (r : R) (A : Matrix l m α) (B : Matrix n p α) :
    A ⊗ₖₜ[R] (r • B) = r • A ⊗ₖₜ B 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) A (r • B) = r • Matrix.kroneckerMap (fun x x_1 => x ⊗ₜ[R] x_1) A B

full_name: Matrix.diagonal_kroneckerTMul_diagonal
code: theorem diagonal_kroneckerTMul_diagonal [DecidableEq m] [DecidableEq n] (a : m → α) (b : n → α) :
    diagonal a ⊗ₖₜ[R] diagonal b = diagonal fun mn => a mn.1 ⊗ₜ b mn.2 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) (Matrix.diagonal a) (Matrix.diagonal b) =
  Matrix.diagonal fun mn => a mn.1 ⊗ₜ[R] b mn.2

full_name: Matrix.kroneckerTMul_diagonal
code: theorem kroneckerTMul_diagonal [DecidableEq n] (A : Matrix l m α) (b : n → α) :
    A ⊗ₖₜ[R] diagonal b = blockDiagonal fun i => A.map fun a => a ⊗ₜ[R] b i 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) A (Matrix.diagonal b) =
  Matrix.blockDiagonal fun i => A.map fun a => a ⊗ₜ[R] b i

full_name: Matrix.diagonal_kroneckerTMul
code: theorem diagonal_kroneckerTMul [DecidableEq l] (a : l → α) (B : Matrix m n α) :
    diagonal a ⊗ₖₜ[R] B =
      Matrix.reindex (Equiv.prodComm _ _) (Equiv.prodComm _ _)
        (blockDiagonal fun i => B.map fun b => a i ⊗ₜ[R] b) 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) (Matrix.diagonal a) B =
  (Matrix.reindex (Equiv.prodComm m l) (Equiv.prodComm n l)) (Matrix.blockDiagonal fun i => B.map fun b => a i ⊗ₜ[R] b)

full_name: Matrix.kroneckerTMul_assoc
code: theorem kroneckerTMul_assoc (A : Matrix l m α) (B : Matrix n p β) (C : Matrix q r γ) :
    reindex (Equiv.prodAssoc l n q) (Equiv.prodAssoc m p r)
        (((A ⊗ₖₜ[R] B) ⊗ₖₜ[R] C).map (TensorProduct.assoc R α β γ)) =
      A ⊗ₖₜ[R] B ⊗ₖₜ[R] C 
goal: (Matrix.reindex (Equiv.prodAssoc l n q) (Equiv.prodAssoc m p r))
    ((Matrix.kroneckerMap (TensorProduct.tmul R) (Matrix.kroneckerMap (TensorProduct.tmul R) A B) C).map
      ⇑(TensorProduct.assoc R α β γ)) =
  Matrix.kroneckerMap (TensorProduct.tmul R) A (Matrix.kroneckerMap (TensorProduct.tmul R) B C)

full_name: Matrix.kroneckerTMul_assoc'
code: @[simp]
theorem kroneckerTMul_assoc' (A : Matrix l m α) (B : Matrix n p β) (C : Matrix q r γ) :
    submatrix (((A ⊗ₖₜ[R] B) ⊗ₖₜ[R] C).map (TensorProduct.assoc R α β γ))
      (Equiv.prodAssoc l n q).symm (Equiv.prodAssoc m p r).symm = A ⊗ₖₜ[R] B ⊗ₖₜ[R] C 
goal: ((Matrix.kroneckerMap (TensorProduct.tmul R) (Matrix.kroneckerMap (TensorProduct.tmul R) A B) C).map
        ⇑(TensorProduct.assoc R α β γ)).submatrix
    ⇑(Equiv.prodAssoc l n q).symm ⇑(Equiv.prodAssoc m p r).symm =
  Matrix.kroneckerMap (TensorProduct.tmul R) A (Matrix.kroneckerMap (TensorProduct.tmul R) B C)

full_name: Matrix.trace_kroneckerTMul
code: theorem trace_kroneckerTMul [Fintype m] [Fintype n] (A : Matrix m m α) (B : Matrix n n β) :
    trace (A ⊗ₖₜ[R] B) = trace A ⊗ₜ[R] trace B 
goal: (Matrix.kroneckerMap (TensorProduct.tmul R) A B).trace = A.trace ⊗ₜ[R] B.trace

full_name: Matrix.one_kroneckerTMul_one
code: @[simp]
theorem one_kroneckerTMul_one [DecidableEq m] [DecidableEq n] :
    (1 : Matrix m m α) ⊗ₖₜ[R] (1 : Matrix n n α) = 1 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) 1 1 = 1

full_name: Matrix.mul_kroneckerTMul_mul
code: theorem mul_kroneckerTMul_mul [Fintype m] [Fintype m'] (A : Matrix l m α) (B : Matrix m n α)
    (A' : Matrix l' m' β) (B' : Matrix m' n' β) :
    (A * B) ⊗ₖₜ[R] (A' * B') = A ⊗ₖₜ[R] A' * B ⊗ₖₜ[R] B' 
goal: Matrix.kroneckerMap (TensorProduct.tmul R) (A * B) (A' * B') =
  Matrix.kroneckerMap (TensorProduct.tmul R) A A' * Matrix.kroneckerMap (TensorProduct.tmul R) B B'

full_name: Matrix.det_kroneckerTMul
code: theorem det_kroneckerTMul [Fintype m] [Fintype n] [DecidableEq m] [DecidableEq n]
    (A : Matrix m m α) (B : Matrix n n β) :
    det (A ⊗ₖₜ[R] B) = (det A ^ Fintype.card n) ⊗ₜ[R] (det B ^ Fintype.card m) 
goal: (Matrix.kroneckerMap (TensorProduct.tmul R) A B).det = (A.det ^ Fintype.card n) ⊗ₜ[R] (B.det ^ Fintype.card m)