|
| 1 | +/- |
| 2 | +Copyright (c) 2019 Johannes Hölzl. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Johannes Hölzl, Patrick Massot, Casper Putz, Anne Baanen |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module linear_algebra.matrix.trace |
| 7 | +! leanprover-community/mathlib commit 32b08ef840dd25ca2e47e035c5da03ce16d2dc3c |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Data.Matrix.Basic |
| 12 | + |
| 13 | +/-! |
| 14 | +# Trace of a matrix |
| 15 | +
|
| 16 | +This file defines the trace of a matrix, the map sending a matrix to the sum of its diagonal |
| 17 | +entries. |
| 18 | +
|
| 19 | +See also `LinearAlgebra.Trace` for the trace of an endomorphism. |
| 20 | +
|
| 21 | +## Tags |
| 22 | +
|
| 23 | +matrix, trace, diagonal |
| 24 | +
|
| 25 | +-/ |
| 26 | + |
| 27 | + |
| 28 | +open BigOperators Matrix |
| 29 | + |
| 30 | +namespace Matrix |
| 31 | + |
| 32 | +variable {ι m n p : Type _} {α R S : Type _} |
| 33 | + |
| 34 | +variable [Fintype m] [Fintype n] [Fintype p] |
| 35 | + |
| 36 | +section AddCommMonoid |
| 37 | + |
| 38 | +variable [AddCommMonoid R] |
| 39 | + |
| 40 | +/-- The trace of a square matrix. For more bundled versions, see: |
| 41 | +* `Matrix.traceAddMonoidHom` |
| 42 | +* `Matrix.traceLinearMap` |
| 43 | +-/ |
| 44 | +def trace (A : Matrix n n R) : R := |
| 45 | + ∑ i, diag A i |
| 46 | +#align matrix.trace Matrix.trace |
| 47 | + |
| 48 | +variable (n R) |
| 49 | + |
| 50 | +@[simp] |
| 51 | +theorem trace_zero : trace (0 : Matrix n n R) = 0 := |
| 52 | + (Finset.sum_const (0 : R)).trans <| smul_zero _ |
| 53 | +#align matrix.trace_zero Matrix.trace_zero |
| 54 | + |
| 55 | +variable {n R} |
| 56 | + |
| 57 | +@[simp] |
| 58 | +theorem trace_add (A B : Matrix n n R) : trace (A + B) = trace A + trace B := |
| 59 | + Finset.sum_add_distrib |
| 60 | +#align matrix.trace_add Matrix.trace_add |
| 61 | + |
| 62 | +@[simp] |
| 63 | +theorem trace_smul [Monoid α] [DistribMulAction α R] (r : α) (A : Matrix n n R) : |
| 64 | + trace (r • A) = r • trace A := |
| 65 | + Finset.smul_sum.symm |
| 66 | +#align matrix.trace_smul Matrix.trace_smul |
| 67 | + |
| 68 | +@[simp] |
| 69 | +theorem trace_transpose (A : Matrix n n R) : trace Aᵀ = trace A := |
| 70 | + rfl |
| 71 | +#align matrix.trace_transpose Matrix.trace_transpose |
| 72 | + |
| 73 | +@[simp] |
| 74 | +theorem trace_conjTranspose [StarAddMonoid R] (A : Matrix n n R) : trace Aᴴ = star (trace A) := |
| 75 | + (star_sum _ _).symm |
| 76 | +#align matrix.trace_conj_transpose Matrix.trace_conjTranspose |
| 77 | + |
| 78 | +variable (n α R) |
| 79 | + |
| 80 | +/-- `Matrix.trace` as an `AddMonoidHom` -/ |
| 81 | +@[simps] |
| 82 | +def traceAddMonoidHom : Matrix n n R →+ R where |
| 83 | + toFun := trace |
| 84 | + map_zero' := trace_zero n R |
| 85 | + map_add' := trace_add |
| 86 | +#align matrix.trace_add_monoid_hom Matrix.traceAddMonoidHom |
| 87 | + |
| 88 | +/-- `Matrix.trace` as a `LinearMap` -/ |
| 89 | +@[simps] |
| 90 | +def traceLinearMap [Semiring α] [Module α R] : Matrix n n R →ₗ[α] R where |
| 91 | + toFun := trace |
| 92 | + map_add' := trace_add |
| 93 | + map_smul' := trace_smul |
| 94 | +#align matrix.trace_linear_map Matrix.traceLinearMap |
| 95 | + |
| 96 | +variable {n α R} |
| 97 | + |
| 98 | +@[simp] |
| 99 | +theorem trace_list_sum (l : List (Matrix n n R)) : trace l.sum = (l.map trace).sum := |
| 100 | + map_list_sum (traceAddMonoidHom n R) l |
| 101 | +#align matrix.trace_list_sum Matrix.trace_list_sum |
| 102 | + |
| 103 | +@[simp] |
| 104 | +theorem trace_multiset_sum (s : Multiset (Matrix n n R)) : trace s.sum = (s.map trace).sum := |
| 105 | + map_multiset_sum (traceAddMonoidHom n R) s |
| 106 | +#align matrix.trace_multiset_sum Matrix.trace_multiset_sum |
| 107 | + |
| 108 | +@[simp] |
| 109 | +theorem trace_sum (s : Finset ι) (f : ι → Matrix n n R) : |
| 110 | + trace (∑ i in s, f i) = ∑ i in s, trace (f i) := |
| 111 | + map_sum (traceAddMonoidHom n R) f s |
| 112 | +#align matrix.trace_sum Matrix.trace_sum |
| 113 | + |
| 114 | +end AddCommMonoid |
| 115 | + |
| 116 | +section AddCommGroup |
| 117 | + |
| 118 | +variable [AddCommGroup R] |
| 119 | + |
| 120 | +@[simp] |
| 121 | +theorem trace_sub (A B : Matrix n n R) : trace (A - B) = trace A - trace B := |
| 122 | + Finset.sum_sub_distrib |
| 123 | +#align matrix.trace_sub Matrix.trace_sub |
| 124 | + |
| 125 | +@[simp] |
| 126 | +theorem trace_neg (A : Matrix n n R) : trace (-A) = -trace A := |
| 127 | + Finset.sum_neg_distrib |
| 128 | +#align matrix.trace_neg Matrix.trace_neg |
| 129 | + |
| 130 | +end AddCommGroup |
| 131 | + |
| 132 | +section One |
| 133 | + |
| 134 | +variable [DecidableEq n] [AddCommMonoidWithOne R] |
| 135 | + |
| 136 | +@[simp] |
| 137 | +theorem trace_one : trace (1 : Matrix n n R) = Fintype.card n := by |
| 138 | + simp_rw [trace, diag_one, Pi.one_def, Finset.sum_const, nsmul_one, Finset.card_univ] |
| 139 | +#align matrix.trace_one Matrix.trace_one |
| 140 | + |
| 141 | +end One |
| 142 | + |
| 143 | +section Mul |
| 144 | + |
| 145 | +@[simp] |
| 146 | +theorem trace_transpose_mul [AddCommMonoid R] [Mul R] (A : Matrix m n R) (B : Matrix n m R) : |
| 147 | + trace (Aᵀ ⬝ Bᵀ) = trace (A ⬝ B) := |
| 148 | + Finset.sum_comm |
| 149 | +#align matrix.trace_transpose_mul Matrix.trace_transpose_mul |
| 150 | + |
| 151 | +theorem trace_mul_comm [AddCommMonoid R] [CommSemigroup R] (A : Matrix m n R) (B : Matrix n m R) : |
| 152 | + trace (A ⬝ B) = trace (B ⬝ A) := by rw [← trace_transpose, ← trace_transpose_mul, transpose_mul] |
| 153 | +#align matrix.trace_mul_comm Matrix.trace_mul_comm |
| 154 | + |
| 155 | +theorem trace_mul_cycle [NonUnitalCommSemiring R] (A : Matrix m n R) (B : Matrix n p R) |
| 156 | + (C : Matrix p m R) : trace (A ⬝ B ⬝ C) = trace (C ⬝ A ⬝ B) := by |
| 157 | + rw [trace_mul_comm, Matrix.mul_assoc] |
| 158 | +#align matrix.trace_mul_cycle Matrix.trace_mul_cycle |
| 159 | + |
| 160 | +theorem trace_mul_cycle' [NonUnitalCommSemiring R] (A : Matrix m n R) (B : Matrix n p R) |
| 161 | + (C : Matrix p m R) : trace (A ⬝ (B ⬝ C)) = trace (C ⬝ (A ⬝ B)) := by |
| 162 | + rw [← Matrix.mul_assoc, trace_mul_comm] |
| 163 | +#align matrix.trace_mul_cycle' Matrix.trace_mul_cycle' |
| 164 | + |
| 165 | +@[simp] |
| 166 | +theorem trace_col_mul_row [NonUnitalNonAssocSemiring R] (a b : n → R) : |
| 167 | + trace (col a ⬝ row b) = dotProduct a b := by |
| 168 | + apply Finset.sum_congr rfl |
| 169 | + simp [mul_apply] |
| 170 | +#align matrix.trace_col_mul_row Matrix.trace_col_mul_row |
| 171 | + |
| 172 | +end Mul |
| 173 | + |
| 174 | +section Fin |
| 175 | + |
| 176 | +variable [AddCommMonoid R] |
| 177 | + |
| 178 | +/-! ### Special cases for `Fin n` |
| 179 | +
|
| 180 | +While `simp [Fin.sum_univ_succ]` can prove these, we include them for convenience and consistency |
| 181 | +with `Matrix.det_fin_two` etc. |
| 182 | +-/ |
| 183 | + |
| 184 | + |
| 185 | +@[simp] |
| 186 | +theorem trace_fin_zero (A : Matrix (Fin 0) (Fin 0) R) : trace A = 0 := |
| 187 | + rfl |
| 188 | +#align matrix.trace_fin_zero Matrix.trace_fin_zero |
| 189 | + |
| 190 | +theorem trace_fin_one (A : Matrix (Fin 1) (Fin 1) R) : trace A = A 0 0 := |
| 191 | + add_zero _ |
| 192 | +#align matrix.trace_fin_one Matrix.trace_fin_one |
| 193 | + |
| 194 | +theorem trace_fin_two (A : Matrix (Fin 2) (Fin 2) R) : trace A = A 0 0 + A 1 1 := |
| 195 | + congr_arg ((· + ·) _) (add_zero (A 1 1)) |
| 196 | +#align matrix.trace_fin_two Matrix.trace_fin_two |
| 197 | + |
| 198 | +theorem trace_fin_three (A : Matrix (Fin 3) (Fin 3) R) : trace A = A 0 0 + A 1 1 + A 2 2 := by |
| 199 | + rw [← add_zero (A 2 2), add_assoc] |
| 200 | + rfl |
| 201 | +#align matrix.trace_fin_three Matrix.trace_fin_three |
| 202 | + |
| 203 | +end Fin |
| 204 | + |
| 205 | +end Matrix |
0 commit comments