[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁴ : Fintype n
inst✝³ : Fintype o
inst✝² : CommRing R
inst✝¹ : StrongRankCondition R
inst✝ : DecidableEq n
⊢ rank 1 = Fintype.card n
[PROOFSTEP]
rw [rank, mulVecLin_one, LinearMap.range_id, finrank_top, finrank_pi]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : Nontrivial R
⊢ rank 0 = 0
[PROOFSTEP]
rw [rank, mulVecLin_zero, LinearMap.range_zero, finrank_bot]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix m n R
⊢ rank A ≤ Fintype.card n
[PROOFSTEP]
haveI : Module.Finite R (n → R) := Module.Finite.pi
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix m n R
this : Module.Finite R (n → R)
⊢ rank A ≤ Fintype.card n
[PROOFSTEP]
haveI : Module.Free R (n → R) := Module.Free.pi _ _
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix m n R
this✝ : Module.Finite R (n → R)
this : Module.Free R (n → R)
⊢ rank A ≤ Fintype.card n
[PROOFSTEP]
exact A.mulVecLin.finrank_range_le.trans_eq (finrank_pi _)
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix m n R
B : Matrix n o R
⊢ rank (A * B) ≤ rank A
[PROOFSTEP]
rw [rank, rank, mulVecLin_mul]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix m n R
B : Matrix n o R
⊢ finrank R { x // x ∈ LinearMap.range (LinearMap.comp (mulVecLin A) (mulVecLin B)) } ≤
    finrank R { x // x ∈ LinearMap.range (mulVecLin A) }
[PROOFSTEP]
exact Cardinal.toNat_le_of_le_of_lt_aleph0 (rank_lt_aleph0 _ _) (LinearMap.rank_comp_le_left _ _)
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix l m R
B : Matrix m n R
⊢ rank (A * B) ≤ rank B
[PROOFSTEP]
rw [rank, rank, mulVecLin_mul]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix l m R
B : Matrix m n R
⊢ finrank R { x // x ∈ LinearMap.range (LinearMap.comp (mulVecLin A) (mulVecLin B)) } ≤
    finrank R { x // x ∈ LinearMap.range (mulVecLin B) }
[PROOFSTEP]
exact finrank_le_finrank_of_rank_le_rank (LinearMap.lift_rank_comp_le_right _ _) (rank_lt_aleph0 _ _)
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁴ : Fintype n
inst✝³ : Fintype o
inst✝² : CommRing R
inst✝¹ : StrongRankCondition R
inst✝ : DecidableEq n
A : (Matrix n n R)ˣ
⊢ rank ↑A = Fintype.card n
[PROOFSTEP]
refine' le_antisymm (rank_le_card_width A) _
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁴ : Fintype n
inst✝³ : Fintype o
inst✝² : CommRing R
inst✝¹ : StrongRankCondition R
inst✝ : DecidableEq n
A : (Matrix n n R)ˣ
⊢ Fintype.card n ≤ rank ↑A
[PROOFSTEP]
have := rank_mul_le_left (A : Matrix n n R) (↑A⁻¹ : Matrix n n R)
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁴ : Fintype n
inst✝³ : Fintype o
inst✝² : CommRing R
inst✝¹ : StrongRankCondition R
inst✝ : DecidableEq n
A : (Matrix n n R)ˣ
this : rank (↑A * ↑A⁻¹) ≤ rank ↑A
⊢ Fintype.card n ≤ rank ↑A
[PROOFSTEP]
rwa [← Units.val_mul, mul_inv_self, Units.val_one, rank_one] at this
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁴ : Fintype n
inst✝³ : Fintype o
inst✝² : CommRing R
inst✝¹ : StrongRankCondition R
inst✝ : DecidableEq n
A : Matrix n n R
h : IsUnit A
⊢ rank A = Fintype.card n
[PROOFSTEP]
obtain ⟨A, rfl⟩ := h
[GOAL]
case intro
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁴ : Fintype n
inst✝³ : Fintype o
inst✝² : CommRing R
inst✝¹ : StrongRankCondition R
inst✝ : DecidableEq n
A : (Matrix n n R)ˣ
⊢ rank ↑A = Fintype.card n
[PROOFSTEP]
exact rank_unit A
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq n
A : Matrix n n R
B : Matrix m n R
hA : IsUnit (det A)
⊢ rank (B * A) = rank B
[PROOFSTEP]
suffices : Function.Surjective A.mulVecLin
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq n
A : Matrix n n R
B : Matrix m n R
hA : IsUnit (det A)
this : Function.Surjective ↑(mulVecLin A)
⊢ rank (B * A) = rank B
[PROOFSTEP]
rw [rank, mulVecLin_mul, LinearMap.range_comp_of_range_eq_top _ (LinearMap.range_eq_top.mpr this), ← rank]
[GOAL]
case this
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq n
A : Matrix n n R
B : Matrix m n R
hA : IsUnit (det A)
⊢ Function.Surjective ↑(mulVecLin A)
[PROOFSTEP]
intro v
[GOAL]
case this
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq n
A : Matrix n n R
B : Matrix m n R
hA : IsUnit (det A)
v : n → R
⊢ ∃ a, ↑(mulVecLin A) a = v
[PROOFSTEP]
exact ⟨(A⁻¹).mulVecLin v, by simp [mul_nonsing_inv _ hA]⟩
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq n
A : Matrix n n R
B : Matrix m n R
hA : IsUnit (det A)
v : n → R
⊢ ↑(mulVecLin A) (↑(mulVecLin A⁻¹) v) = v
[PROOFSTEP]
simp [mul_nonsing_inv _ hA]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq m
A : Matrix m m R
B : Matrix m n R
hA : IsUnit (det A)
⊢ rank (A * B) = rank B
[PROOFSTEP]
let b : Basis m R (m → R) := Pi.basisFun R m
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq m
A : Matrix m m R
B : Matrix m n R
hA : IsUnit (det A)
b : Basis m R (m → R) := Pi.basisFun R m
⊢ rank (A * B) = rank B
[PROOFSTEP]
replace hA : IsUnit (LinearMap.toMatrix b b A.mulVecLin).det := by convert hA; rw [← LinearEquiv.eq_symm_apply]; rfl
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq m
A : Matrix m m R
B : Matrix m n R
hA : IsUnit (det A)
b : Basis m R (m → R) := Pi.basisFun R m
⊢ IsUnit (det (↑(LinearMap.toMatrix b b) (mulVecLin A)))
[PROOFSTEP]
convert hA
[GOAL]
case h.e'_3.h.e'_6
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq m
A : Matrix m m R
B : Matrix m n R
hA : IsUnit (det A)
b : Basis m R (m → R) := Pi.basisFun R m
⊢ ↑(LinearMap.toMatrix b b) (mulVecLin A) = A
[PROOFSTEP]
rw [← LinearEquiv.eq_symm_apply]
[GOAL]
case h.e'_3.h.e'_6
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq m
A : Matrix m m R
B : Matrix m n R
hA : IsUnit (det A)
b : Basis m R (m → R) := Pi.basisFun R m
⊢ mulVecLin A = ↑(LinearEquiv.symm (LinearMap.toMatrix b b)) A
[PROOFSTEP]
rfl
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq m
A : Matrix m m R
B : Matrix m n R
b : Basis m R (m → R) := Pi.basisFun R m
hA : IsUnit (det (↑(LinearMap.toMatrix b b) (mulVecLin A)))
⊢ rank (A * B) = rank B
[PROOFSTEP]
have hAB : mulVecLin (A * B) = (LinearEquiv.ofIsUnitDet hA).comp (mulVecLin B) := by ext; simp
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq m
A : Matrix m m R
B : Matrix m n R
b : Basis m R (m → R) := Pi.basisFun R m
hA : IsUnit (det (↑(LinearMap.toMatrix b b) (mulVecLin A)))
⊢ mulVecLin (A * B) = LinearMap.comp (↑(LinearEquiv.ofIsUnitDet hA)) (mulVecLin B)
[PROOFSTEP]
ext
[GOAL]
case h.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq m
A : Matrix m m R
B : Matrix m n R
b : Basis m R (m → R) := Pi.basisFun R m
hA : IsUnit (det (↑(LinearMap.toMatrix b b) (mulVecLin A)))
x✝¹ : n → R
x✝ : m
⊢ ↑(mulVecLin (A * B)) x✝¹ x✝ = ↑(LinearMap.comp (↑(LinearEquiv.ofIsUnitDet hA)) (mulVecLin B)) x✝¹ x✝
[PROOFSTEP]
simp
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : DecidableEq m
A : Matrix m m R
B : Matrix m n R
b : Basis m R (m → R) := Pi.basisFun R m
hA : IsUnit (det (↑(LinearMap.toMatrix b b) (mulVecLin A)))
hAB : mulVecLin (A * B) = LinearMap.comp (↑(LinearEquiv.ofIsUnitDet hA)) (mulVecLin B)
⊢ rank (A * B) = rank B
[PROOFSTEP]
rw [rank, rank, hAB, LinearMap.range_comp, LinearEquiv.finrank_map_eq]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁴ : Fintype n
inst✝³ : Fintype o
inst✝² : CommRing R
inst✝¹ : StrongRankCondition R
inst✝ : Fintype m
f : n → m
e : n ≃ m
A : Matrix m m R
⊢ rank (submatrix A f ↑e) ≤ rank A
[PROOFSTEP]
rw [rank, rank, mulVecLin_submatrix, LinearMap.range_comp, LinearMap.range_comp,
  show LinearMap.funLeft R R e.symm = LinearEquiv.funCongrLeft R R e.symm from rfl, LinearEquiv.range,
  Submodule.map_top]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁴ : Fintype n
inst✝³ : Fintype o
inst✝² : CommRing R
inst✝¹ : StrongRankCondition R
inst✝ : Fintype m
f : n → m
e : n ≃ m
A : Matrix m m R
⊢ finrank R { x // x ∈ Submodule.map (LinearMap.funLeft R R f) (LinearMap.range (mulVecLin A)) } ≤
    finrank R { x // x ∈ LinearMap.range (mulVecLin A) }
[PROOFSTEP]
exact Submodule.finrank_map_le _ _
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : Fintype m
e₁ e₂ : m ≃ n
A : Matrix m m R
⊢ rank (↑(reindex e₁ e₂) A) = rank A
[PROOFSTEP]
rw [rank, rank, mulVecLin_reindex, LinearMap.range_comp, LinearMap.range_comp, LinearEquiv.range, Submodule.map_top,
  LinearEquiv.finrank_map_eq]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : Fintype m
A : Matrix m m R
e₁ e₂ : n ≃ m
⊢ rank (submatrix A ↑e₁ ↑e₂) = rank A
[PROOFSTEP]
simpa only [reindex_apply] using rank_reindex e₁.symm e₂.symm A
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
⊢ rank A = finrank R { x // x ∈ LinearMap.range (↑(toLin v₂ v₁) A) }
[PROOFSTEP]
let e₁ := (Pi.basisFun R m).equiv v₁ (Equiv.refl _)
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
⊢ rank A = finrank R { x // x ∈ LinearMap.range (↑(toLin v₂ v₁) A) }
[PROOFSTEP]
let e₂ := (Pi.basisFun R n).equiv v₂ (Equiv.refl _)
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
⊢ rank A = finrank R { x // x ∈ LinearMap.range (↑(toLin v₂ v₁) A) }
[PROOFSTEP]
have range_e₂ : LinearMap.range e₂ = ⊤ := by
  rw [LinearMap.range_eq_top]
  exact e₂.surjective
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
⊢ LinearMap.range e₂ = ⊤
[PROOFSTEP]
rw [LinearMap.range_eq_top]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
⊢ Function.Surjective ↑e₂
[PROOFSTEP]
exact e₂.surjective
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ rank A = finrank R { x // x ∈ LinearMap.range (↑(toLin v₂ v₁) A) }
[PROOFSTEP]
refine' LinearEquiv.finrank_eq (e₁.ofSubmodules _ _ _)
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ Submodule.map (↑e₁) (LinearMap.range (mulVecLin A)) = LinearMap.range (↑(toLin v₂ v₁) A)
[PROOFSTEP]
rw [← LinearMap.range_comp, ← LinearMap.range_comp_of_range_eq_top (toLin v₂ v₁ A) range_e₂]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ LinearMap.range (LinearMap.comp (↑e₁) (mulVecLin A)) = LinearMap.range (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂)
[PROOFSTEP]
congr 1
[GOAL]
case e_f
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ LinearMap.comp (↑e₁) (mulVecLin A) = LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂
[PROOFSTEP]
apply LinearMap.pi_ext'
[GOAL]
case e_f.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
⊢ ∀ (i : n),
    LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i) =
      LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)
[PROOFSTEP]
rintro i
[GOAL]
case e_f.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
⊢ LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i) =
    LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)
[PROOFSTEP]
apply LinearMap.ext_ring
[GOAL]
case e_f.h.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1
[PROOFSTEP]
have aux₁ := toLin_self (Pi.basisFun R n) (Pi.basisFun R m) A i
[GOAL]
case e_f.h.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
aux₁ :
  ↑(↑(toLin (Pi.basisFun R n) (Pi.basisFun R m)) A) (↑(Pi.basisFun R n) i) =
    Finset.sum Finset.univ fun j => A j i • ↑(Pi.basisFun R m) j
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1
[PROOFSTEP]
have aux₂ := Basis.equiv_apply (Pi.basisFun R n) i v₂
[GOAL]
case e_f.h.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
aux₁ :
  ↑(↑(toLin (Pi.basisFun R n) (Pi.basisFun R m)) A) (↑(Pi.basisFun R n) i) =
    Finset.sum Finset.univ fun j => A j i • ↑(Pi.basisFun R m) j
aux₂ : ∀ (e : n ≃ n), ↑(Basis.equiv (Pi.basisFun R n) v₂ e) (↑(Pi.basisFun R n) i) = ↑v₂ (↑e i)
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1
[PROOFSTEP]
rw [toLin_eq_toLin', toLin'_apply'] at aux₁
[GOAL]
case e_f.h.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
aux₁ : ↑(mulVecLin A) (↑(Pi.basisFun R n) i) = Finset.sum Finset.univ fun j => A j i • ↑(Pi.basisFun R m) j
aux₂ : ∀ (e : n ≃ n), ↑(Basis.equiv (Pi.basisFun R n) v₂ e) (↑(Pi.basisFun R n) i) = ↑v₂ (↑e i)
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1
[PROOFSTEP]
rw [Pi.basisFun_apply, LinearMap.coe_stdBasis] at aux₁ aux₂
[GOAL]
case e_f.h.h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁷ : Fintype n
inst✝⁶ : Fintype o
inst✝⁵ : CommRing R
inst✝⁴ : DecidableEq n
M₁ : Type u_6
M₂ : Type u_7
inst✝³ : AddCommGroup M₁
inst✝² : AddCommGroup M₂
inst✝¹ : Module R M₁
inst✝ : Module R M₂
A : Matrix m n R
v₁ : Basis m R M₁
v₂ : Basis n R M₂
e₁ : (m → R) ≃ₗ[R] M₁ := Basis.equiv (Pi.basisFun R m) v₁ (Equiv.refl m)
e₂ : (n → R) ≃ₗ[R] M₂ := Basis.equiv (Pi.basisFun R n) v₂ (Equiv.refl n)
range_e₂ : LinearMap.range e₂ = ⊤
i : n
aux₁ : ↑(mulVecLin A) (Pi.single i 1) = Finset.sum Finset.univ fun j => A j i • ↑(Pi.basisFun R m) j
aux₂ : ∀ (e : n ≃ n), ↑(Basis.equiv (Pi.basisFun R n) v₂ e) (Pi.single i 1) = ↑v₂ (↑e i)
⊢ ↑(LinearMap.comp (LinearMap.comp (↑e₁) (mulVecLin A)) (LinearMap.single i)) 1 =
    ↑(LinearMap.comp (LinearMap.comp (↑(toLin v₂ v₁) A) ↑e₂) (LinearMap.single i)) 1
[PROOFSTEP]
simp only [LinearMap.comp_apply, LinearEquiv.coe_coe, Equiv.refl_apply, aux₁, aux₂, LinearMap.coe_single, toLin_self,
  LinearEquiv.map_sum, LinearEquiv.map_smul, Basis.equiv_apply]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix m n R
⊢ rank A ≤ Fintype.card m
[PROOFSTEP]
haveI : Module.Finite R (m → R) := Module.Finite.pi
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix m n R
this : Module.Finite R (m → R)
⊢ rank A ≤ Fintype.card m
[PROOFSTEP]
haveI : Module.Free R (m → R) := Module.Free.pi _ _
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : CommRing R
inst✝ : StrongRankCondition R
A : Matrix m n R
this✝ : Module.Finite R (m → R)
this : Module.Free R (m → R)
⊢ rank A ≤ Fintype.card m
[PROOFSTEP]
exact (Submodule.finrank_le _).trans (finrank_pi R).le
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝² : Fintype n
inst✝¹ : Fintype o
inst✝ : CommRing R
A : Matrix m n R
⊢ rank A = finrank R { x // x ∈ Submodule.span R (Set.range Aᵀ) }
[PROOFSTEP]
rw [rank, Matrix.range_mulVecLin]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁴ : Fintype n
inst✝³ : Fintype o
inst✝² : Field R
inst✝¹ : DecidableEq m
inst✝ : DecidableEq R
w : m → R
⊢ rank (diagonal w) = Fintype.card { i // w i ≠ 0 }
[PROOFSTEP]
rw [Matrix.rank, ← Matrix.toLin'_apply', FiniteDimensional.finrank, ← LinearMap.rank, LinearMap.rank_diagonal,
  Cardinal.toNat_cast]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : Fintype o
inst✝³ : Fintype m
inst✝² : Field R
inst✝¹ : PartialOrder R
inst✝ : StarOrderedRing R
A : Matrix m n R
⊢ LinearMap.ker (mulVecLin (Aᴴ * A)) = LinearMap.ker (mulVecLin A)
[PROOFSTEP]
ext x
[GOAL]
case h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : Fintype o
inst✝³ : Fintype m
inst✝² : Field R
inst✝¹ : PartialOrder R
inst✝ : StarOrderedRing R
A : Matrix m n R
x : n → R
⊢ x ∈ LinearMap.ker (mulVecLin (Aᴴ * A)) ↔ x ∈ LinearMap.ker (mulVecLin A)
[PROOFSTEP]
simp only [LinearMap.mem_ker, mulVecLin_apply, conjTranspose_mul_self_mulVec_eq_zero]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : Fintype o
inst✝³ : Fintype m
inst✝² : Field R
inst✝¹ : PartialOrder R
inst✝ : StarOrderedRing R
A : Matrix m n R
⊢ rank (Aᴴ * A) = rank A
[PROOFSTEP]
dsimp only [rank]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : Fintype o
inst✝³ : Fintype m
inst✝² : Field R
inst✝¹ : PartialOrder R
inst✝ : StarOrderedRing R
A : Matrix m n R
⊢ finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᴴ * A)) } = finrank R { x // x ∈ LinearMap.range (mulVecLin A) }
[PROOFSTEP]
refine' add_left_injective (finrank R (LinearMap.ker (mulVecLin A))) _
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : Fintype o
inst✝³ : Fintype m
inst✝² : Field R
inst✝¹ : PartialOrder R
inst✝ : StarOrderedRing R
A : Matrix m n R
⊢ (fun x => x + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) })
      (finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᴴ * A)) }) =
    (fun x => x + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) })
      (finrank R { x // x ∈ LinearMap.range (mulVecLin A) })
[PROOFSTEP]
dsimp only
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : Fintype o
inst✝³ : Fintype m
inst✝² : Field R
inst✝¹ : PartialOrder R
inst✝ : StarOrderedRing R
A : Matrix m n R
⊢ finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᴴ * A)) } + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) } =
    finrank R { x // x ∈ LinearMap.range (mulVecLin A) } + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) }
[PROOFSTEP]
trans
  finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᴴ * A)) } +
    finrank R { x // x ∈ LinearMap.ker (mulVecLin (Aᴴ * A)) }
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : Fintype o
inst✝³ : Fintype m
inst✝² : Field R
inst✝¹ : PartialOrder R
inst✝ : StarOrderedRing R
A : Matrix m n R
⊢ finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᴴ * A)) } + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) } =
    finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᴴ * A)) } +
      finrank R { x // x ∈ LinearMap.ker (mulVecLin (Aᴴ * A)) }
[PROOFSTEP]
rw [ker_mulVecLin_conjTranspose_mul_self]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : Fintype o
inst✝³ : Fintype m
inst✝² : Field R
inst✝¹ : PartialOrder R
inst✝ : StarOrderedRing R
A : Matrix m n R
⊢ finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᴴ * A)) } +
      finrank R { x // x ∈ LinearMap.ker (mulVecLin (Aᴴ * A)) } =
    finrank R { x // x ∈ LinearMap.range (mulVecLin A) } + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) }
[PROOFSTEP]
simp only [LinearMap.finrank_range_add_finrank_ker]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝⁵ : Fintype n
inst✝⁴ : Fintype o
inst✝³ : Fintype m
inst✝² : Field R
inst✝¹ : PartialOrder R
inst✝ : StarOrderedRing R
A : Matrix m n R
⊢ rank (A * Aᴴ) = rank A
[PROOFSTEP]
simpa only [rank_conjTranspose, conjTranspose_conjTranspose] using rank_conjTranspose_mul_self Aᴴ
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ LinearMap.ker (mulVecLin (Aᵀ * A)) = LinearMap.ker (mulVecLin A)
[PROOFSTEP]
ext x
[GOAL]
case h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
x : n → R
⊢ x ∈ LinearMap.ker (mulVecLin (Aᵀ * A)) ↔ x ∈ LinearMap.ker (mulVecLin A)
[PROOFSTEP]
simp only [LinearMap.mem_ker, mulVecLin_apply, ← mulVec_mulVec]
[GOAL]
case h
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
x : n → R
⊢ mulVec Aᵀ (mulVec A x) = 0 ↔ mulVec A x = 0
[PROOFSTEP]
constructor
[GOAL]
case h.mp
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
x : n → R
⊢ mulVec Aᵀ (mulVec A x) = 0 → mulVec A x = 0
[PROOFSTEP]
intro h
[GOAL]
case h.mp
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
x : n → R
h : mulVec Aᵀ (mulVec A x) = 0
⊢ mulVec A x = 0
[PROOFSTEP]
replace h := congr_arg (dotProduct x) h
[GOAL]
case h.mp
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
x : n → R
h : x ⬝ᵥ mulVec Aᵀ (mulVec A x) = x ⬝ᵥ 0
⊢ mulVec A x = 0
[PROOFSTEP]
rwa [dotProduct_mulVec, dotProduct_zero, vecMul_transpose, dotProduct_self_eq_zero] at h
[GOAL]
case h.mpr
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
x : n → R
⊢ mulVec A x = 0 → mulVec Aᵀ (mulVec A x) = 0
[PROOFSTEP]
intro h
[GOAL]
case h.mpr
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
x : n → R
h : mulVec A x = 0
⊢ mulVec Aᵀ (mulVec A x) = 0
[PROOFSTEP]
rw [h, mulVec_zero]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ rank (Aᵀ * A) = rank A
[PROOFSTEP]
dsimp only [rank]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᵀ * A)) } = finrank R { x // x ∈ LinearMap.range (mulVecLin A) }
[PROOFSTEP]
refine' add_left_injective (finrank R <| LinearMap.ker A.mulVecLin) _
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ (fun x => x + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) })
      (finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᵀ * A)) }) =
    (fun x => x + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) })
      (finrank R { x // x ∈ LinearMap.range (mulVecLin A) })
[PROOFSTEP]
dsimp only
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᵀ * A)) } + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) } =
    finrank R { x // x ∈ LinearMap.range (mulVecLin A) } + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) }
[PROOFSTEP]
trans
  finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᵀ * A)) } +
    finrank R { x // x ∈ LinearMap.ker (mulVecLin (Aᵀ * A)) }
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᵀ * A)) } + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) } =
    finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᵀ * A)) } +
      finrank R { x // x ∈ LinearMap.ker (mulVecLin (Aᵀ * A)) }
[PROOFSTEP]
rw [ker_mulVecLin_transpose_mul_self]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ finrank R { x // x ∈ LinearMap.range (mulVecLin (Aᵀ * A)) } +
      finrank R { x // x ∈ LinearMap.ker (mulVecLin (Aᵀ * A)) } =
    finrank R { x // x ∈ LinearMap.range (mulVecLin A) } + finrank R { x // x ∈ LinearMap.ker (mulVecLin A) }
[PROOFSTEP]
simp only [LinearMap.finrank_range_add_finrank_ker]
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : Fintype m
inst✝ : LinearOrderedField R
A : Matrix m n R
⊢ rank (A * Aᵀ) = rank A
[PROOFSTEP]
simpa only [rank_transpose, transpose_transpose] using rank_transpose_mul_self Aᵀ
[GOAL]
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : LinearOrderedField R
inst✝ : Finite m
A : Matrix m n R
⊢ rank A = finrank R { x // x ∈ Submodule.span R (Set.range A) }
[PROOFSTEP]
cases nonempty_fintype m
[GOAL]
case intro
l : Type u_1
m : Type u_2
n : Type u_3
o : Type u_4
R : Type u_5
m_fin : Fintype m
inst✝³ : Fintype n
inst✝² : Fintype o
inst✝¹ : LinearOrderedField R
inst✝ : Finite m
A : Matrix m n R
val✝ : Fintype m
⊢ rank A = finrank R { x // x ∈ Submodule.span R (Set.range A) }
[PROOFSTEP]
rw [← rank_transpose, rank_eq_finrank_span_cols, transpose_transpose]