l3lab/ntp-mathlib huggingface dataset:
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
      _ = star v ⬝ᵥ mulVec A (mulVec (A - B) v)  + star v ⬝ᵥ mulVec (A - B) (mulVec B v) := by
        rw [mulVec_mulVec, mulVec_mulVec, ← dotProduct_add, ← add_mulVec, mul_sub, sub_mul,
          add_sub, sub_add_cancel, pow_two, pow_two]
      _ = t * (star v ⬝ᵥ mulVec A v) + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v := by
        rw [hv', mulVec_smul, dotProduct_smul, IsROrC.real_smul_eq_coe_mul,
          dotProduct_mulVec _ (A - B), hA.1.sub hB.1]
      _ = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v) := by
        simp_rw [← star_mulVec, hv', mul_add, ← IsROrC.real_smul_eq_coe_mul, ← smul_dotProduct]
        congr 2 with i
        simp only [Pi.star_apply, Pi.smul_apply, IsROrC.real_smul_eq_coe_mul, star_mul',
          IsROrC.star_def, IsROrC.conj_ofReal]
  replace h_sum : star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v = 0
  · rw [eq_comm, ← mul_zero (t : 𝕜)] at h_sum
    exact mul_left_cancel₀ (IsROrC.ofReal_ne_zero.mpr ht) h_sum
  have h_van : star v ⬝ᵥ mulVec A v = 0 ∧ star v ⬝ᵥ mulVec B v = 0
  · refine ⟨le_antisymm ?_ (hA.2 v), le_antisymm ?_ (hB.2 v)⟩
    · rw [add_comm, add_eq_zero_iff_eq_neg] at h_sum
      simpa only [h_sum, neg_nonneg] using hB.2 v
    · simpa only [add_eq_zero_iff_eq_neg.mp h_sum, neg_nonneg] using hA.2 v
  have aux : star v ⬝ᵥ mulVec (A - B) v = 0
  · 

Proof state:
case aux
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
h_sum : star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v = 0
h_van : star v ⬝ᵥ mulVec A v = 0 ∧ star v ⬝ᵥ mulVec B v = 0
⊢ star v ⬝ᵥ mulVec (A - B) v = 0

Next tactic:
rw [sub_mulVec, dotProduct_sub, h_van.1, h_van.2, sub_zero]
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
      _ = star v ⬝ᵥ mulVec A (mulVec (A - B) v)  + star v ⬝ᵥ mulVec (A - B) (mulVec B v) := by
        rw [mulVec_mulVec, mulVec_mulVec, ← dotProduct_add, ← add_mulVec, mul_sub, sub_mul,
          add_sub, sub_add_cancel, pow_two, pow_two]
      _ = t * (star v ⬝ᵥ mulVec A v) + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v := by
        rw [hv', mulVec_smul, dotProduct_smul, IsROrC.real_smul_eq_coe_mul,
          dotProduct_mulVec _ (A - B), hA.1.sub hB.1]
      _ = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v) := by
        simp_rw [← star_mulVec, hv', mul_add, ← IsROrC.real_smul_eq_coe_mul, ← smul_dotProduct]
        congr 2 with i
        simp only [Pi.star_apply, Pi.smul_apply, IsROrC.real_smul_eq_coe_mul, star_mul',
          IsROrC.star_def, IsROrC.conj_ofReal]
  replace h_sum : star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v = 0
  · rw [eq_comm, ← mul_zero (t : 𝕜)] at h_sum
    exact mul_left_cancel₀ (IsROrC.ofReal_ne_zero.mpr ht) h_sum
  have h_van : star v ⬝ᵥ mulVec A v = 0 ∧ star v ⬝ᵥ mulVec B v = 0
  · refine ⟨le_antisymm ?_ (hA.2 v), le_antisymm ?_ (hB.2 v)⟩
    · rw [add_comm, add_eq_zero_iff_eq_neg] at h_sum
      simpa only [h_sum, neg_nonneg] using hB.2 v
    · simpa only [add_eq_zero_iff_eq_neg.mp h_sum, neg_nonneg] using hA.2 v
  have aux : star v ⬝ᵥ mulVec (A - B) v = 0
  · rw [sub_mulVec, dotProduct_sub, h_van.1, h_van.2, sub_zero]
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
h_sum : star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v = 0
h_van : star v ⬝ᵥ mulVec A v = 0 ∧ star v ⬝ᵥ mulVec B v = 0
aux : star v ⬝ᵥ mulVec (A - B) v = 0
⊢ False

Next tactic:
rw [hv', dotProduct_smul, IsROrC.real_smul_eq_coe_mul, ← mul_zero ↑t] at aux
lemma eq_of_sq_eq_sq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B ^ 2) : A = B := by
  /- This is deceptively hard, much more difficult than the positive *definite* case. We follow a
  clever proof due to Koeber and Schäfer. The idea is that if `A ≠ B`, then `A - B` has a nonzero
  real eigenvalue, with eigenvector `v`. Then a manipulation using the identity
  `A ^ 2 - B ^ 2 = A * (A - B) + (A - B) * B` leads to the conclusion that
  `⟨v, A v⟩ + ⟨v, B v⟩ = 0`. Since `A, B` are positive semidefinite, both terms must be zero. Thus
  `⟨v, (A - B) v⟩ = 0`, but this is a nonzero scalar multiple of `⟨v, v⟩`, contradiction. -/
  by_contra h_ne
  let ⟨v, t, ht, hv, hv'⟩ := (hA.1.sub hB.1).exists_eigenvector_of_ne_zero (sub_ne_zero.mpr h_ne)
  have h_sum : 0 = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v)
  · calc
      0 = star v ⬝ᵥ mulVec (A ^ 2 - B ^ 2) v := by rw [hAB, sub_self, zero_mulVec, dotProduct_zero]
      _ = star v ⬝ᵥ mulVec A (mulVec (A - B) v)  + star v ⬝ᵥ mulVec (A - B) (mulVec B v) := by
        rw [mulVec_mulVec, mulVec_mulVec, ← dotProduct_add, ← add_mulVec, mul_sub, sub_mul,
          add_sub, sub_add_cancel, pow_two, pow_two]
      _ = t * (star v ⬝ᵥ mulVec A v) + vecMul (star v) (A - B)ᴴ ⬝ᵥ mulVec B v := by
        rw [hv', mulVec_smul, dotProduct_smul, IsROrC.real_smul_eq_coe_mul,
          dotProduct_mulVec _ (A - B), hA.1.sub hB.1]
      _ = t * (star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v) := by
        simp_rw [← star_mulVec, hv', mul_add, ← IsROrC.real_smul_eq_coe_mul, ← smul_dotProduct]
        congr 2 with i
        simp only [Pi.star_apply, Pi.smul_apply, IsROrC.real_smul_eq_coe_mul, star_mul',
          IsROrC.star_def, IsROrC.conj_ofReal]
  replace h_sum : star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v = 0
  · rw [eq_comm, ← mul_zero (t : 𝕜)] at h_sum
    exact mul_left_cancel₀ (IsROrC.ofReal_ne_zero.mpr ht) h_sum
  have h_van : star v ⬝ᵥ mulVec A v = 0 ∧ star v ⬝ᵥ mulVec B v = 0
  · refine ⟨le_antisymm ?_ (hA.2 v), le_antisymm ?_ (hB.2 v)⟩
    · rw [add_comm, add_eq_zero_iff_eq_neg] at h_sum
      simpa only [h_sum, neg_nonneg] using hB.2 v
    · simpa only [add_eq_zero_iff_eq_neg.mp h_sum, neg_nonneg] using hA.2 v
  have aux : star v ⬝ᵥ mulVec (A - B) v = 0
  · rw [sub_mulVec, dotProduct_sub, h_van.1, h_van.2, sub_zero]
  rw [hv', dotProduct_smul, IsROrC.real_smul_eq_coe_mul, ← mul_zero ↑t] at aux
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B ^ 2
h_ne : ¬A = B
v : n → 𝕜
t : ℝ
ht : t ≠ 0
hv : v ≠ 0
hv' : mulVec (A - B) v = t • v
h_sum : star v ⬝ᵥ mulVec A v + star v ⬝ᵥ mulVec B v = 0
h_van : star v ⬝ᵥ mulVec A v = 0 ∧ star v ⬝ᵥ mulVec B v = 0
aux : ↑t * star v ⬝ᵥ v = ↑t * 0
⊢ False

Next tactic:
exact hv <| Matrix.dotProduct_star_self_eq_zero.mp <| mul_left_cancel₀
    (IsROrC.ofReal_ne_zero.mpr ht) aux
lemma eq_sqrt_of_sq_eq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B) : A = hB.sqrt := by
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
B : Matrix n n 𝕜
hB : PosSemidef B
hAB : A ^ 2 = B
⊢ A = hB.sqrt

Next tactic:
subst B
lemma eq_sqrt_of_sq_eq {B : Matrix n n 𝕜} (hB : PosSemidef B) (hAB : A ^ 2 = B) : A = hB.sqrt := by
  subst B
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
hB : PosSemidef (A ^ 2)
⊢ A = hB.sqrt

Next tactic:
rw [hA.sqrt_sq]
@[simp]
theorem posSemidef_submatrix_equiv {M : Matrix n n R} (e : m ≃ n) :
    (M.submatrix e e).PosSemidef ↔ M.PosSemidef :=
  ⟨fun h => by 

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁵ : Fintype m
inst✝⁴ : Fintype n
inst✝³ : CommRing R
inst✝² : PartialOrder R
inst✝¹ : StarOrderedRing R
inst✝ : IsROrC 𝕜
M : Matrix n n R
e : m ≃ n
h : PosSemidef (submatrix M ⇑e ⇑e)
⊢ PosSemidef M

Next tactic:
simpa using h.submatrix e.symm
/-- The conjugate transpose of a matrix mulitplied by the matrix is positive semidefinite -/
theorem posSemidef_conjTranspose_mul_self (A : Matrix m n R) : PosSemidef (Aᴴ * A) := by
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁵ : Fintype m
inst✝⁴ : Fintype n
inst✝³ : CommRing R
inst✝² : PartialOrder R
inst✝¹ : StarOrderedRing R
inst✝ : IsROrC 𝕜
A : Matrix m n R
⊢ PosSemidef (Aᴴ * A)

Next tactic:
refine ⟨isHermitian_transpose_mul_self _, fun x => ?_⟩
/-- The conjugate transpose of a matrix mulitplied by the matrix is positive semidefinite -/
theorem posSemidef_conjTranspose_mul_self (A : Matrix m n R) : PosSemidef (Aᴴ * A) := by
  refine ⟨isHermitian_transpose_mul_self _, fun x => ?_⟩
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁵ : Fintype m
inst✝⁴ : Fintype n
inst✝³ : CommRing R
inst✝² : PartialOrder R
inst✝¹ : StarOrderedRing R
inst✝ : IsROrC 𝕜
A : Matrix m n R
x : n → R
⊢ 0 ≤ star x ⬝ᵥ mulVec (Aᴴ * A) x

Next tactic:
rw [← mulVec_mulVec, dotProduct_mulVec, vecMul_conjTranspose, star_star]
/-- The conjugate transpose of a matrix mulitplied by the matrix is positive semidefinite -/
theorem posSemidef_conjTranspose_mul_self (A : Matrix m n R) : PosSemidef (Aᴴ * A) := by
  refine ⟨isHermitian_transpose_mul_self _, fun x => ?_⟩
  rw [← mulVec_mulVec, dotProduct_mulVec, vecMul_conjTranspose, star_star]
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁵ : Fintype m
inst✝⁴ : Fintype n
inst✝³ : CommRing R
inst✝² : PartialOrder R
inst✝¹ : StarOrderedRing R
inst✝ : IsROrC 𝕜
A : Matrix m n R
x : n → R
⊢ 0 ≤ star (mulVec A x) ⬝ᵥ mulVec A x

Next tactic:
exact Finset.sum_nonneg fun i _ => star_mul_self_nonneg _
/-- A matrix multiplied by its conjugate transpose is positive semidefinite -/
theorem posSemidef_self_mul_conjTranspose (A : Matrix m n R) : PosSemidef (A * Aᴴ) :=
  by 

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁵ : Fintype m
inst✝⁴ : Fintype n
inst✝³ : CommRing R
inst✝² : PartialOrder R
inst✝¹ : StarOrderedRing R
inst✝ : IsROrC 𝕜
A : Matrix m n R
⊢ PosSemidef (A * Aᴴ)

Next tactic:
simpa only [conjTranspose_conjTranspose] using posSemidef_conjTranspose_mul_self Aᴴ
/-- A matrix is positive semidefinite if and only if it has the form `Bᴴ * B` for some `B`. -/
lemma posSemidef_iff_eq_transpose_mul_self [DecidableEq n] {A : Matrix n n 𝕜} :
    PosSemidef A ↔ ∃ (B : Matrix n n 𝕜), A = Bᴴ * B := by
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
⊢ PosSemidef A ↔ ∃ B, A = Bᴴ * B

Next tactic:
refine ⟨fun hA ↦ ⟨hA.sqrt, ?_⟩, fun ⟨B, hB⟩ ↦ (hB ▸ posSemidef_conjTranspose_mul_self B)⟩
/-- A matrix is positive semidefinite if and only if it has the form `Bᴴ * B` for some `B`. -/
lemma posSemidef_iff_eq_transpose_mul_self [DecidableEq n] {A : Matrix n n 𝕜} :
    PosSemidef A ↔ ∃ (B : Matrix n n 𝕜), A = Bᴴ * B := by
  refine ⟨fun hA ↦ ⟨hA.sqrt, ?_⟩, fun ⟨B, hB⟩ ↦ (hB ▸ posSemidef_conjTranspose_mul_self B)⟩
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
⊢ A = hA.sqrtᴴ * hA.sqrt

Next tactic:
simp_rw [← PosSemidef.sq_sqrt hA, pow_two]
/-- A matrix is positive semidefinite if and only if it has the form `Bᴴ * B` for some `B`. -/
lemma posSemidef_iff_eq_transpose_mul_self [DecidableEq n] {A : Matrix n n 𝕜} :
    PosSemidef A ↔ ∃ (B : Matrix n n 𝕜), A = Bᴴ * B := by
  refine ⟨fun hA ↦ ⟨hA.sqrt, ?_⟩, fun ⟨B, hB⟩ ↦ (hB ▸ posSemidef_conjTranspose_mul_self B)⟩
  simp_rw [← PosSemidef.sq_sqrt hA, pow_two]
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
⊢ hA.sqrt * hA.sqrt = hA.sqrtᴴ * hA.sqrt

Next tactic:
rw [hA.posSemidef_sqrt.1]
lemma IsHermitian.posSemidef_of_eigenvalues_nonneg [DecidableEq n] {A : Matrix n n 𝕜}
    (hA : IsHermitian A) (h : ∀ i : n, 0 ≤ hA.eigenvalues i) : PosSemidef A := by
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : IsHermitian A
h : ∀ (i : n), 0 ≤ eigenvalues hA i
⊢ PosSemidef A

Next tactic:
simp_rw [hA.conjTranspose_eigenvectorMatrix.symm ▸ hA.spectral_theorem']
lemma IsHermitian.posSemidef_of_eigenvalues_nonneg [DecidableEq n] {A : Matrix n n 𝕜}
    (hA : IsHermitian A) (h : ∀ i : n, 0 ≤ hA.eigenvalues i) : PosSemidef A := by
  simp_rw [hA.conjTranspose_eigenvectorMatrix.symm ▸ hA.spectral_theorem']
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : IsHermitian A
h : ∀ (i : n), 0 ≤ eigenvalues hA i
⊢ PosSemidef (eigenvectorMatrix hA * diagonal (IsROrC.ofReal ∘ eigenvalues hA) * (eigenvectorMatrix hA)ᴴ)

Next tactic:
refine (posSemidef_diagonal_iff.mpr fun i ↦ ?_).mul_mul_conjTranspose_same _
lemma IsHermitian.posSemidef_of_eigenvalues_nonneg [DecidableEq n] {A : Matrix n n 𝕜}
    (hA : IsHermitian A) (h : ∀ i : n, 0 ≤ hA.eigenvalues i) : PosSemidef A := by
  simp_rw [hA.conjTranspose_eigenvectorMatrix.symm ▸ hA.spectral_theorem']
  refine (posSemidef_diagonal_iff.mpr fun i ↦ ?_).mul_mul_conjTranspose_same _
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : IsHermitian A
h : ∀ (i : n), 0 ≤ eigenvalues hA i
i : n
⊢ 0 ≤ (IsROrC.ofReal ∘ eigenvalues hA) i

Next tactic:
rw [IsROrC.le_iff_re_im]
lemma IsHermitian.posSemidef_of_eigenvalues_nonneg [DecidableEq n] {A : Matrix n n 𝕜}
    (hA : IsHermitian A) (h : ∀ i : n, 0 ≤ hA.eigenvalues i) : PosSemidef A := by
  simp_rw [hA.conjTranspose_eigenvectorMatrix.symm ▸ hA.spectral_theorem']
  refine (posSemidef_diagonal_iff.mpr fun i ↦ ?_).mul_mul_conjTranspose_same _
  rw [IsROrC.le_iff_re_im]
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : IsHermitian A
h : ∀ (i : n), 0 ≤ eigenvalues hA i
i : n
⊢ IsROrC.re 0 ≤ IsROrC.re ((IsROrC.ofReal ∘ eigenvalues hA) i) ∧
    IsROrC.im 0 = IsROrC.im ((IsROrC.ofReal ∘ eigenvalues hA) i)

Next tactic:
simpa using h i
/-- For `A` positive semidefinite, we have `x⋆ A x = 0` iff `A x = 0`. -/
theorem PosSemidef.dotProduct_mulVec_zero_iff [DecidableEq n]
    {A : Matrix n n 𝕜} (hA : PosSemidef A) (x : n → 𝕜) :
    star x ⬝ᵥ mulVec A x = 0 ↔ mulVec A x = 0 := by
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
x : n → 𝕜
⊢ star x ⬝ᵥ mulVec A x = 0 ↔ mulVec A x = 0

Next tactic:
constructor
/-- For `A` positive semidefinite, we have `x⋆ A x = 0` iff `A x = 0`. -/
theorem PosSemidef.dotProduct_mulVec_zero_iff [DecidableEq n]
    {A : Matrix n n 𝕜} (hA : PosSemidef A) (x : n → 𝕜) :
    star x ⬝ᵥ mulVec A x = 0 ↔ mulVec A x = 0 := by
  constructor
  · 

Proof state:
case mp
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
x : n → 𝕜
⊢ star x ⬝ᵥ mulVec A x = 0 → mulVec A x = 0

Next tactic:
obtain ⟨B, rfl⟩ := posSemidef_iff_eq_transpose_mul_self.mp hA
/-- For `A` positive semidefinite, we have `x⋆ A x = 0` iff `A x = 0`. -/
theorem PosSemidef.dotProduct_mulVec_zero_iff [DecidableEq n]
    {A : Matrix n n 𝕜} (hA : PosSemidef A) (x : n → 𝕜) :
    star x ⬝ᵥ mulVec A x = 0 ↔ mulVec A x = 0 := by
  constructor
  · obtain ⟨B, rfl⟩ := posSemidef_iff_eq_transpose_mul_self.mp hA
    

Proof state:
case mp.intro
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
x : n → 𝕜
B : Matrix n n 𝕜
hA : PosSemidef (Bᴴ * B)
⊢ star x ⬝ᵥ mulVec (Bᴴ * B) x = 0 → mulVec (Bᴴ * B) x = 0

Next tactic:
rw [← Matrix.mulVec_mulVec, dotProduct_mulVec,
      vecMul_conjTranspose, star_star, dotProduct_star_self_eq_zero]
/-- For `A` positive semidefinite, we have `x⋆ A x = 0` iff `A x = 0`. -/
theorem PosSemidef.dotProduct_mulVec_zero_iff [DecidableEq n]
    {A : Matrix n n 𝕜} (hA : PosSemidef A) (x : n → 𝕜) :
    star x ⬝ᵥ mulVec A x = 0 ↔ mulVec A x = 0 := by
  constructor
  · obtain ⟨B, rfl⟩ := posSemidef_iff_eq_transpose_mul_self.mp hA
    rw [← Matrix.mulVec_mulVec, dotProduct_mulVec,
      vecMul_conjTranspose, star_star, dotProduct_star_self_eq_zero]
    

Proof state:
case mp.intro
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
x : n → 𝕜
B : Matrix n n 𝕜
hA : PosSemidef (Bᴴ * B)
⊢ mulVec B x = 0 → mulVec Bᴴ (mulVec B x) = 0

Next tactic:
intro h0
/-- For `A` positive semidefinite, we have `x⋆ A x = 0` iff `A x = 0`. -/
theorem PosSemidef.dotProduct_mulVec_zero_iff [DecidableEq n]
    {A : Matrix n n 𝕜} (hA : PosSemidef A) (x : n → 𝕜) :
    star x ⬝ᵥ mulVec A x = 0 ↔ mulVec A x = 0 := by
  constructor
  · obtain ⟨B, rfl⟩ := posSemidef_iff_eq_transpose_mul_self.mp hA
    rw [← Matrix.mulVec_mulVec, dotProduct_mulVec,
      vecMul_conjTranspose, star_star, dotProduct_star_self_eq_zero]
    intro h0
    

Proof state:
case mp.intro
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
x : n → 𝕜
B : Matrix n n 𝕜
hA : PosSemidef (Bᴴ * B)
h0 : mulVec B x = 0
⊢ mulVec Bᴴ (mulVec B x) = 0

Next tactic:
rw [h0, mulVec_zero]
/-- For `A` positive semidefinite, we have `x⋆ A x = 0` iff `A x = 0`. -/
theorem PosSemidef.dotProduct_mulVec_zero_iff [DecidableEq n]
    {A : Matrix n n 𝕜} (hA : PosSemidef A) (x : n → 𝕜) :
    star x ⬝ᵥ mulVec A x = 0 ↔ mulVec A x = 0 := by
  constructor
  · obtain ⟨B, rfl⟩ := posSemidef_iff_eq_transpose_mul_self.mp hA
    rw [← Matrix.mulVec_mulVec, dotProduct_mulVec,
      vecMul_conjTranspose, star_star, dotProduct_star_self_eq_zero]
    intro h0
    rw [h0, mulVec_zero]
  · 

Proof state:
case mpr
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
x : n → 𝕜
⊢ mulVec A x = 0 → star x ⬝ᵥ mulVec A x = 0

Next tactic:
intro h0
/-- For `A` positive semidefinite, we have `x⋆ A x = 0` iff `A x = 0`. -/
theorem PosSemidef.dotProduct_mulVec_zero_iff [DecidableEq n]
    {A : Matrix n n 𝕜} (hA : PosSemidef A) (x : n → 𝕜) :
    star x ⬝ᵥ mulVec A x = 0 ↔ mulVec A x = 0 := by
  constructor
  · obtain ⟨B, rfl⟩ := posSemidef_iff_eq_transpose_mul_self.mp hA
    rw [← Matrix.mulVec_mulVec, dotProduct_mulVec,
      vecMul_conjTranspose, star_star, dotProduct_star_self_eq_zero]
    intro h0
    rw [h0, mulVec_zero]
  · intro h0
    

Proof state:
case mpr
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
x : n → 𝕜
h0 : mulVec A x = 0
⊢ star x ⬝ᵥ mulVec A x = 0

Next tactic:
rw [h0, dotProduct_zero]
/-- For `A` positive semidefinite, we have `x⋆ A x = 0` iff `A x = 0` (linear maps version). -/
theorem PosSemidef.toLinearMap₂'_zero_iff [DecidableEq n]
    {A : Matrix n n 𝕜} (hA : PosSemidef A) (x : n → 𝕜) :
    Matrix.toLinearMap₂' A (star x) x = 0 ↔ Matrix.toLin' A x = 0 := by
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁶ : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : CommRing R
inst✝³ : PartialOrder R
inst✝² : StarOrderedRing R
inst✝¹ : IsROrC 𝕜
inst✝ : DecidableEq n
A : Matrix n n 𝕜
hA : PosSemidef A
x : n → 𝕜
⊢ ((toLinearMap₂' A) (star x)) x = 0 ↔ (toLin' A) x = 0

Next tactic:
simpa only [toLinearMap₂'_apply', toLin'_apply] using hA.dotProduct_mulVec_zero_iff x
theorem posSemidef {M : Matrix n n R} (hM : M.PosDef) : M.PosSemidef := by
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁵ : Fintype m
inst✝⁴ : Fintype n
inst✝³ : CommRing R
inst✝² : PartialOrder R
inst✝¹ : StarOrderedRing R
inst✝ : IsROrC 𝕜
M : Matrix n n R
hM : PosDef M
⊢ PosSemidef M

Next tactic:
refine' ⟨hM.1, _⟩
theorem posSemidef {M : Matrix n n R} (hM : M.PosDef) : M.PosSemidef := by
  refine' ⟨hM.1, _⟩
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁵ : Fintype m
inst✝⁴ : Fintype n
inst✝³ : CommRing R
inst✝² : PartialOrder R
inst✝¹ : StarOrderedRing R
inst✝ : IsROrC 𝕜
M : Matrix n n R
hM : PosDef M
⊢ ∀ (x : n → R), 0 ≤ star x ⬝ᵥ mulVec M x

Next tactic:
intro x
theorem posSemidef {M : Matrix n n R} (hM : M.PosDef) : M.PosSemidef := by
  refine' ⟨hM.1, _⟩
  intro x
  

Proof state:
m : Type u_1
n : Type u_2
R : Type u_3
𝕜 : Type u_4
inst✝⁵ : Fintype m
inst✝⁴ : Fintype n
inst✝³ : CommRing R
inst✝² : PartialOrder R
inst✝¹ : StarOrderedRing R
inst✝ : IsROrC 𝕜
M : Matrix n n R
hM : PosDef M
x : n → R
⊢ 0 ≤ star x ⬝ᵥ mulVec M x

Next tactic:
by_cases hx : x = 0