File: Mathlib/LinearAlgebra/Matrix/Charpoly/Coeff.lean

full_name: Matrix.charmatrix_apply_natDegree
code: theorem charmatrix_apply_natDegree [Nontrivial R] (i j : n) :
    (charmatrix M i j).natDegree = ite (i = j) 1 0 
goal: (M.charmatrix i j).natDegree = if i = j then 1 else 0

full_name: Matrix.charmatrix_apply_natDegree_le
code: theorem charmatrix_apply_natDegree_le (i j : n) :
    (charmatrix M i j).natDegree ≤ ite (i = j) 1 0 
goal: (M.charmatrix i j).natDegree ≤ if i = j then 1 else 0

full_name: Matrix.charpoly_sub_diagonal_degree_lt
code: theorem charpoly_sub_diagonal_degree_lt :
    (M.charpoly - ∏ i : n, (X - C (M i i))).degree < ↑(Fintype.card n - 1) 
goal: (M.charpoly - ∏ i : n, (Polynomial.X - Polynomial.C (M i i))).degree < ↑(Fintype.card n - 1)

full_name: Matrix.charpoly_coeff_eq_prod_coeff_of_le
code: theorem charpoly_coeff_eq_prod_coeff_of_le {k : ℕ} (h : Fintype.card n - 1 ≤ k) :
    M.charpoly.coeff k = (∏ i : n, (X - C (M i i))).coeff k 
goal: M.charpoly.coeff k = (∏ i : n, (Polynomial.X - Polynomial.C (M i i))).coeff k

full_name: Matrix.det_of_card_zero
code: theorem det_of_card_zero (h : Fintype.card n = 0) (M : Matrix n n R) : M.det = 1 
goal: M.det = 1

full_name: Matrix.charpoly_degree_eq_dim
code: theorem charpoly_degree_eq_dim [Nontrivial R] (M : Matrix n n R) :
    M.charpoly.degree = Fintype.card n 
goal: M.charpoly.degree = ↑(Fintype.card n)

full_name: Matrix.charpoly_natDegree_eq_dim
code: @[simp] theorem charpoly_natDegree_eq_dim [Nontrivial R] (M : Matrix n n R) :
    M.charpoly.natDegree = Fintype.card n 
goal: M.charpoly.natDegree = Fintype.card n

full_name: Matrix.charpoly_monic
code: theorem charpoly_monic (M : Matrix n n R) : M.charpoly.Monic 
goal: M.charpoly.Monic

full_name: Matrix.trace_eq_neg_charpoly_coeff
code: /-- See also `Matrix.coeff_charpolyRev_eq_neg_trace`. -/
theorem trace_eq_neg_charpoly_coeff [Nonempty n] (M : Matrix n n R) :
    trace M = -M.charpoly.coeff (Fintype.card n - 1) 
goal: M.trace = -M.charpoly.coeff (Fintype.card n - 1)

full_name: Matrix.matPolyEquiv_symm_map_eval
code: theorem matPolyEquiv_symm_map_eval (M : (Matrix n n R)[X]) (r : R) :
    (matPolyEquiv.symm M).map (eval r) = M.eval (scalar n r) 
goal: (matPolyEquiv.symm M).map (Polynomial.eval r) = Polynomial.eval ((Matrix.scalar n) r) M

full_name: Matrix.matPolyEquiv_eval_eq_map
code: theorem matPolyEquiv_eval_eq_map (M : Matrix n n R[X]) (r : R) :
    (matPolyEquiv M).eval (scalar n r) = M.map (eval r) 
goal: Polynomial.eval ((Matrix.scalar n) r) (matPolyEquiv M) = M.map (Polynomial.eval r)

full_name: Matrix.matPolyEquiv_eval
code: theorem matPolyEquiv_eval (M : Matrix n n R[X]) (r : R) (i j : n) :
    (matPolyEquiv M).eval (scalar n r) i j = (M i j).eval r 
goal: Polynomial.eval ((Matrix.scalar n) r) (matPolyEquiv M) i j = Polynomial.eval r (M i j)

full_name: Matrix.eval_det
code: theorem eval_det (M : Matrix n n R[X]) (r : R) :
    Polynomial.eval r M.det = (Polynomial.eval (scalar n r) (matPolyEquiv M)).det 
goal: Polynomial.eval r M.det = (Polynomial.eval ((Matrix.scalar n) r) (matPolyEquiv M)).det

full_name: Matrix.det_eq_sign_charpoly_coeff
code: theorem det_eq_sign_charpoly_coeff (M : Matrix n n R) :
    M.det = (-1) ^ Fintype.card n * M.charpoly.coeff 0 
goal: M.det = (-1) ^ Fintype.card n * M.charpoly.coeff 0

full_name: Matrix.eval_det_add_X_smul
code: lemma eval_det_add_X_smul (A : Matrix n n R[X]) (M : Matrix n n R) :
    (det (A + (X : R[X]) • M.map C)).eval 0 = (det A).eval 0 
goal: Polynomial.eval 0 (A + Polynomial.X • M.map ⇑Polynomial.C).det = Polynomial.eval 0 A.det

full_name: Matrix.derivative_det_one_add_X_smul_aux
code: lemma derivative_det_one_add_X_smul_aux {n} (M : Matrix (Fin n) (Fin n) R) :
    (derivative <| det (1 + (X : R[X]) • M.map C)).eval 0 = trace M 
goal: Polynomial.eval 0 (Polynomial.derivative (1 + Polynomial.X • M.map ⇑Polynomial.C).det) = M.trace

full_name: Matrix.derivative_det_one_add_X_smul
code: /-- The derivative of `det (1 + M X)` at `0` is the trace of `M`. -/
lemma derivative_det_one_add_X_smul (M : Matrix n n R) :
    (derivative <| det (1 + (X : R[X]) • M.map C)).eval 0 = trace M 
goal: Polynomial.eval 0 (Polynomial.derivative (1 + Polynomial.X • M.map ⇑Polynomial.C).det) = M.trace

full_name: Matrix.coeff_det_one_add_X_smul_one
code: lemma coeff_det_one_add_X_smul_one (M : Matrix n n R) :
    (det (1 + (X : R[X]) • M.map C)).coeff 1 = trace M 
goal: (1 + Polynomial.X • M.map ⇑Polynomial.C).det.coeff 1 = M.trace

full_name: Matrix.det_one_add_X_smul
code: lemma det_one_add_X_smul (M : Matrix n n R) :
    det (1 + (X : R[X]) • M.map C) =
      (1 : R[X]) + trace M • X + (det (1 + (X : R[X]) • M.map C)).divX.divX * X ^ 2 
goal: (1 + Polynomial.X • M.map ⇑Polynomial.C).det =
  1 + M.trace • Polynomial.X + (1 + Polynomial.X • M.map ⇑Polynomial.C).det.divX.divX * Polynomial.X ^ 2

full_name: Matrix.det_one_add_smul
code: /-- The first two terms of the taylor expansion of `det (1 + r • M)` at `r = 0`. -/
lemma det_one_add_smul (r : R) (M : Matrix n n R) :
    det (1 + r • M) =
      1 + trace M * r + (det (1 + (X : R[X]) • M.map C)).divX.divX.eval r * r ^ 2 
goal: (1 + r • M).det = 1 + M.trace * r + Polynomial.eval r (1 + Polynomial.X • M.map ⇑Polynomial.C).det.divX.divX * r ^ 2

full_name: matPolyEquiv_eq_X_pow_sub_C
code: theorem matPolyEquiv_eq_X_pow_sub_C {K : Type*} (k : ℕ) [Field K] (M : Matrix n n K) :
    matPolyEquiv ((expand K k : K[X] →+* K[X]).mapMatrix (charmatrix (M ^ k))) =
      X ^ k - C (M ^ k) 
goal: matPolyEquiv ((↑(Polynomial.expand K k)).mapMatrix (M ^ k).charmatrix) = Polynomial.X ^ k - Polynomial.C (M ^ k)

full_name: Matrix.aeval_eq_aeval_mod_charpoly
code: /-- Any matrix polynomial `p` is equivalent under evaluation to `p %ₘ M.charpoly`; that is, `p`
is equivalent to a polynomial with degree less than the dimension of the matrix. -/
theorem aeval_eq_aeval_mod_charpoly (M : Matrix n n R) (p : R[X]) :
    aeval M p = aeval M (p %ₘ M.charpoly) 
goal: (Polynomial.aeval M) p = (Polynomial.aeval M) (p %ₘ M.charpoly)

full_name: Matrix.pow_eq_aeval_mod_charpoly
code: /-- Any matrix power can be computed as the sum of matrix powers less than `Fintype.card n`.

TODO: add the statement for negative powers phrased with `zpow`. -/
theorem pow_eq_aeval_mod_charpoly (M : Matrix n n R) (k : ℕ) :
    M ^ k = aeval M (X ^ k %ₘ M.charpoly) 
goal: M ^ k = (Polynomial.aeval M) (Polynomial.X ^ k %ₘ M.charpoly)

full_name: Matrix.coeff_charpoly_mem_ideal_pow
code: theorem coeff_charpoly_mem_ideal_pow {I : Ideal R} (h : ∀ i j, M i j ∈ I) (k : ℕ) :
    M.charpoly.coeff k ∈ I ^ (Fintype.card n - k) 
goal: M.charpoly.coeff k ∈ I ^ (Fintype.card n - k)

full_name: Matrix.charpolyRev
code: /-- The reverse of the characteristic polynomial of a matrix.

It has some advantages over the characteristic polynomial, including the fact that it can be
extended to infinite dimensions (for appropriate operators). In such settings it is known as the
"characteristic power series". -/
def charpolyRev (M : Matrix n n R) : R[X] 
goal: R[X]

full_name: Matrix.reverse_charpoly
code: lemma reverse_charpoly (M : Matrix n n R) :
    M.charpoly.reverse = M.charpolyRev 
goal: M.charpoly.reverse = M.charpolyRev

full_name: Matrix.eval_charpolyRev
code: @[simp] lemma eval_charpolyRev :
    eval 0 M.charpolyRev = 1 
goal: Polynomial.eval 0 M.charpolyRev = 1

full_name: Matrix.coeff_charpolyRev_eq_neg_trace
code: @[simp] lemma coeff_charpolyRev_eq_neg_trace (M : Matrix n n R) :
    coeff M.charpolyRev 1 = - trace M 
goal: M.charpolyRev.coeff 1 = -M.trace

full_name: Matrix.isUnit_charpolyRev_of_isNilpotent
code: lemma isUnit_charpolyRev_of_isNilpotent (hM : IsNilpotent M) :
    IsUnit M.charpolyRev 
goal: IsUnit M.charpolyRev

full_name: Matrix.isNilpotent_trace_of_isNilpotent
code: lemma isNilpotent_trace_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (trace M) 
goal: IsNilpotent M.trace

full_name: Matrix.isNilpotent_charpoly_sub_pow_of_isNilpotent
code: lemma isNilpotent_charpoly_sub_pow_of_isNilpotent (hM : IsNilpotent M) :
    IsNilpotent (M.charpoly - X ^ (Fintype.card n)) 
goal: IsNilpotent (M.charpoly - Polynomial.X ^ Fintype.card n)