Imports
/-
Copyright (c) 2024 Joseph Tooby-Smith. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Joseph Tooby-Smith
-/
module
public import Mathlib.LinearAlgebra.Eigenspace.Basic
public import Mathlib.Analysis.InnerProductSpace.PiL2The group SO(3)
@[expose] public section
The group of 3×3 real matrices with determinant 1 and A * Aᵀ = 1.
def SO3 : Type := {A : Matrix (Fin 3) (Fin 3) ℝ // A.det = 1 ∧ A * Aᵀ = 1}
The instance of a group on SO3.
All goals completed! 🐙⟩
one_mul A := Subtype.ext (Matrix.one_mul A.1)
mul_one A := Subtype.ext (Matrix.mul_one A.1)
inv A := ⟨A.1ᵀ, by A:SO3⊢ (↑A)ᵀ.det = 1 simp only [det_transpose, A.2] All goals completed! 🐙,
by A:SO3⊢ (↑A)ᵀ * (↑A)ᵀᵀ = 1 simp only [transpose_transpose, mul_eq_one_comm.mpr A.2.2] All goals completed! 🐙⟩
inv_mul_cancel A := Subtype.ext (mul_eq_one_comm.mpr A.2.2)
Notation for the group SO3.
scoped[GroupTheory] notation (name := SO3_notation) "SO(3)" => SO3SO3 has the subtype topology.
instance : TopologicalSpace SO3 := instTopologicalSpaceSubtypelemma coe_inv (A : SO3) : (A⁻¹).1 = A.1⁻¹:=
(inv_eq_left_inv (mul_eq_one_comm.mpr A.2.2)).symm
The inclusion of SO(3) into GL (Fin 3) ℝ.
def toGL : SO(3) →* GL (Fin 3) ℝ where
toFun A := ⟨A.1, (A⁻¹).1, A.2.2, mul_eq_one_comm.mpr A.2.2⟩
map_one' := (GeneralLinearGroup.ext_iff _ 1).mpr fun _=> congrFun rfl
map_mul' _ _ := (GeneralLinearGroup.ext_iff _ _).mpr fun _ => congrFun rfllemma subtype_val_eq_toGL : (Subtype.val : SO3 → Matrix (Fin 3) (Fin 3) ℝ) =
Units.val ∘ toGL.toFun :=
rfl
The inclusion of SO(3) into GL(3,ℝ) is an injection.
lemma toGL_injective : Function.Injective toGL := by ⊢ Function.Injective ⇑toGL
refine fun A B h ↦ Subtype.ext ?_ A:SO(3)B:SO(3)h:toGL A = toGL B⊢ ↑A = ↑B
rwa [@Units.ext_iff A:SO(3)B:SO(3)h:↑(toGL A) = ↑(toGL B)⊢ ↑A = ↑B] A:SO(3)B:SO(3)h:↑(toGL A) = ↑(toGL B)⊢ ↑A = ↑B at h
The inclusion of SO(3) into the monoid of matrices times the opposite of
the monoid of matrices.
@[simps!]
def toProd : SO(3) →* (Matrix (Fin 3) (Fin 3) ℝ) × (Matrix (Fin 3) (Fin 3) ℝ)ᵐᵒᵖ :=
MonoidHom.comp (Units.embedProduct _) toGLlemma toProd_eq_transpose : toProd A = (A.1, ⟨A.1ᵀ⟩) := rfl
lemma toProd_injective : Function.Injective toProd := by ⊢ Function.Injective ⇑toProd
intro A B h A:SO(3)B:SO(3)h:toProd A = toProd B⊢ A = B
rw [toProd_eq_transpose, A:SO(3)B:SO(3)h:(↑A, { unop' := (↑A)ᵀ }) = toProd B⊢ A = B A:SO(3)B:SO(3)h:↑A = ↑B ∧ { unop' := (↑A)ᵀ } = { unop' := (↑B)ᵀ }⊢ A = B toProd_eq_transpose, A:SO(3)B:SO(3)h:(↑A, { unop' := (↑A)ᵀ }) = (↑B, { unop' := (↑B)ᵀ })⊢ A = B A:SO(3)B:SO(3)h:↑A = ↑B ∧ { unop' := (↑A)ᵀ } = { unop' := (↑B)ᵀ }⊢ A = B Prod.mk_inj A:SO(3)B:SO(3)h:↑A = ↑B ∧ { unop' := (↑A)ᵀ } = { unop' := (↑B)ᵀ }⊢ A = B A:SO(3)B:SO(3)h:↑A = ↑B ∧ { unop' := (↑A)ᵀ } = { unop' := (↑B)ᵀ }⊢ A = B] at h A:SO(3)B:SO(3)h:↑A = ↑B ∧ { unop' := (↑A)ᵀ } = { unop' := (↑B)ᵀ }⊢ A = B
exact Subtype.ext h.1 All goals completed! 🐙lemma toProd_continuous : Continuous toProd :=
continuous_prodMk.mpr ⟨continuous_iff_le_induced.mpr fun _ a ↦ a,
Continuous.comp' (MulOpposite.continuous_op)
(Continuous.matrix_transpose (continuous_iff_le_induced.mpr fun _ a ↦ a))⟩
The embedding of SO(3) into the monoid of matrices times the opposite of
the monoid of matrices.
lemma toProd_embedding : IsEmbedding toProd where
injective := toProd_injective
eq_induced := (isInducing_iff ⇑toProd).mp (IsInducing.of_comp toProd_continuous
continuous_fst ((isInducing_iff (Prod.fst ∘ ⇑toProd)).mpr rfl))
The embedding of SO(3) into GL (Fin 3) ℝ.
set_option backward.isDefEq.respectTransparency false in
lemma toGL_embedding : IsEmbedding toGL.toFun where
injective := toGL_injective
eq_induced := by ⊢ instTopologicalSpaceSO3 = TopologicalSpace.induced (↑toGL).toFun Units.instTopologicalSpaceUnits
refine ((fun {X} {t t'} => TopologicalSpace.ext_iff.mpr) ?_).symm ⊢ ∀ (s : Set { A // A.det = 1 ∧ A * Aᵀ = 1 }),
IsOpen[TopologicalSpace.induced (↑toGL).toFun Units.instTopologicalSpaceUnits] s ↔ IsOpen s
intro s s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ IsOpen[TopologicalSpace.induced (↑toGL).toFun Units.instTopologicalSpaceUnits] s ↔ IsOpen s
rw [TopologicalSpace.ext_iff.mp toProd_embedding.eq_induced s s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ IsOpen[TopologicalSpace.induced (↑toGL).toFun Units.instTopologicalSpaceUnits] s ↔
IsOpen[TopologicalSpace.induced (⇑toProd) instTopologicalSpaceProd] s s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ IsOpen[TopologicalSpace.induced (↑toGL).toFun Units.instTopologicalSpaceUnits] s ↔
IsOpen[TopologicalSpace.induced (⇑toProd) instTopologicalSpaceProd] s] s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ IsOpen[TopologicalSpace.induced (↑toGL).toFun Units.instTopologicalSpaceUnits] s ↔
IsOpen[TopologicalSpace.induced (⇑toProd) instTopologicalSpaceProd] s
rw [isOpen_induced_iff, s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ (∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s) ↔ IsOpen[TopologicalSpace.induced (⇑toProd) instTopologicalSpaceProd] s s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ (∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s) ↔ ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s isOpen_induced_iff s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ (∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s) ↔ ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ (∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s) ↔ ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s] s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ (∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s) ↔ ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s
constructor mp s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ (∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s) → ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = smpr s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ (∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s) → ∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s <;> mp s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ (∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s) → ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = smpr s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }⊢ (∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s) → ∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s intro h mpr s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }h:∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s⊢ ∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s <;> mp s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }h:∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s⊢ ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = smpr s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }h:∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s⊢ ∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s obtain ⟨U, hU1, hU2⟩ := h mpr s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }U:Set (Matrix (Fin 3) (Fin 3) ℝ × (Matrix (Fin 3) (Fin 3) ℝ)ᵐᵒᵖ)hU1:IsOpen UhU2:⇑toProd ⁻¹' U = s⊢ ∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s
· mp s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }U:Set (GL (Fin 3) ℝ)hU1:IsOpen UhU2:(↑toGL).toFun ⁻¹' U = s⊢ ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s rw [isOpen_induced_iff mp s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }U:Set (GL (Fin 3) ℝ)hU1:∃ t, IsOpen t ∧ ⇑(Units.embedProduct (Matrix (Fin 3) (Fin 3) ℝ)) ⁻¹' t = UhU2:(↑toGL).toFun ⁻¹' U = s⊢ ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s mp s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }U:Set (GL (Fin 3) ℝ)hU1:∃ t, IsOpen t ∧ ⇑(Units.embedProduct (Matrix (Fin 3) (Fin 3) ℝ)) ⁻¹' t = UhU2:(↑toGL).toFun ⁻¹' U = s⊢ ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s] at hU1mp s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }U:Set (GL (Fin 3) ℝ)hU1:∃ t, IsOpen t ∧ ⇑(Units.embedProduct (Matrix (Fin 3) (Fin 3) ℝ)) ⁻¹' t = UhU2:(↑toGL).toFun ⁻¹' U = s⊢ ∃ t, IsOpen t ∧ ⇑toProd ⁻¹' t = s
aesop All goals completed! 🐙
· mpr s:Set { A // A.det = 1 ∧ A * Aᵀ = 1 }U:Set (Matrix (Fin 3) (Fin 3) ℝ × (Matrix (Fin 3) (Fin 3) ℝ)ᵐᵒᵖ)hU1:IsOpen UhU2:⇑toProd ⁻¹' U = s⊢ ∃ t, IsOpen t ∧ (↑toGL).toFun ⁻¹' t = s exact ⟨(Units.embedProduct _) ⁻¹' U, And.intro (isOpen_induced hU1) hU2⟩ All goals completed! 🐙
The instance of a topological group on SO(3), defined through the embedding of SO(3)
into GL(n).
instance : IsTopologicalGroup SO(3) :=
IsInducing.topologicalGroup toGL toGL_embedding.toIsInducing
The determinant of an SO(3) matrix minus the identity is equal to zero.
lemma det_minus_id (A : SO(3)) : det (A.1 - 1) = 0 := by A:SO(3)⊢ (↑A - 1).det = 0
have h1 : det (A.1 - 1) = - det (A.1 - 1) :=
calc
det (A.1 - 1) = det (A.1 - A.1 * A.1ᵀ) := by A:SO(3)⊢ (↑A - 1).det = (↑A - ↑A * (↑A)ᵀ).det A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 simp [A.2.2] All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0
_ = det A.1 * det (1 - A.1ᵀ) := by A:SO(3)⊢ (↑A - ↑A * (↑A)ᵀ).det = (↑A).det * (1 - (↑A)ᵀ).det A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 rw [← det_mul, A:SO(3)⊢ (↑A - ↑A * (↑A)ᵀ).det = (↑A * (1 - (↑A)ᵀ)).det All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 mul_sub, A:SO(3)⊢ (↑A - ↑A * (↑A)ᵀ).det = (↑A * 1 - ↑A * (↑A)ᵀ).det All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 mul_one A:SO(3)⊢ (↑A - ↑A * (↑A)ᵀ).det = (↑A - ↑A * (↑A)ᵀ).det All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0] All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0
_ = det (1 - A.1ᵀ) := by A:SO(3)⊢ (↑A).det * (1 - (↑A)ᵀ).det = (1 - (↑A)ᵀ).det A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 simp [A.2.1] All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0
_ = det (1 - A.1ᵀ)ᵀ := by A:SO(3)⊢ (1 - (↑A)ᵀ).det = (1 - (↑A)ᵀ)ᵀ.det A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 rw [det_transpose A:SO(3)⊢ (1 - (↑A)ᵀ).det = (1 - (↑A)ᵀ).det All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0] All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0
_ = det (1 - A.1) := rfl
_ = det (- (A.1 - 1)) := by A:SO(3)⊢ (1 - ↑A).det = (-(↑A - 1)).det A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 simp All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0
_ = (- 1) ^ 3 * det (A.1 - 1) := by A:SO(3)⊢ (-(↑A - 1)).det = (-1) ^ 3 * (↑A - 1).det A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 simp only [det_neg, Fintype.card_fin] All goals completed! 🐙 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0
_ = - det (A.1 - 1) := by A:SO(3)⊢ (-1) ^ 3 * (↑A - 1).det = -(↑A - 1).det A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 simp [pow_three] A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0 A:SO(3)h1:(↑A - 1).det = -(↑A - 1).det⊢ (↑A - 1).det = 0
exact CharZero.eq_neg_self_iff.mp h1 All goals completed! 🐙
The determinant of the identity minus an SO(3) matrix is zero.
@[simp]
lemma det_id_minus (A : SO(3)) : det (1 - A.1) = 0 := by A:SO(3)⊢ (1 - ↑A).det = 0
have h1 : det (1 - A.1) = - det (A.1 - 1) := by
calc
det (1 - A.1) = det (- (A.1 - 1)) := by A:SO(3)⊢ (1 - ↑A).det = (-(↑A - 1)).det A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ (1 - ↑A).det = 0 simp All goals completed! 🐙 A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ (1 - ↑A).det = 0
_ = (- 1) ^ 3 * det (A.1 - 1) := by A:SO(3)⊢ (-(↑A - 1)).det = (-1) ^ 3 * (↑A - 1).det A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ (1 - ↑A).det = 0 simp only [det_neg, Fintype.card_fin] All goals completed! 🐙 A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ (1 - ↑A).det = 0
_ = - det (A.1 - 1) := by A:SO(3)⊢ (-1) ^ 3 * (↑A - 1).det = -(↑A - 1).det A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ (1 - ↑A).det = 0 simp [pow_three] A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ (1 - ↑A).det = 0 A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ (1 - ↑A).det = 0
rw [h1, A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ -(↑A - 1).det = 0 A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ -0 = 0 det_minus_id A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ -0 = 0 A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ -0 = 0] A:SO(3)h1:(1 - ↑A).det = -(↑A - 1).det⊢ -0 = 0
exact neg_zero All goals completed! 🐙
For every matrix in SO(3), the real number 1 is in its spectrum.
@[simp]
lemma one_in_spectrum (A : SO(3)) : 1 ∈ spectrum ℝ (A.1) := by A:SO(3)⊢ 1 ∈ spectrum ℝ ↑A
simp [spectrum.mem_iff, _root_.map_one, Matrix.isUnit_iff_isUnit_det] All goals completed! 🐙
The endomorphism of EuclideanSpace ℝ (Fin 3) associated to a element of SO(3).
@[simps!]
def toEnd (A : SO(3)) : End ℝ (EuclideanSpace ℝ (Fin 3)) :=
Matrix.toLin (EuclideanSpace.basisFun (Fin 3) ℝ).toBasis
(EuclideanSpace.basisFun (Fin 3) ℝ).toBasis A.1
Every SO(3) matrix has an eigenvalue equal to 1.
lemma one_is_eigenvalue (A : SO(3)) : A.toEnd.HasEigenvalue 1 := by A:SO(3)⊢ A.toEnd.HasEigenvalue 1
rw [End.hasEigenvalue_iff_mem_spectrum A:SO(3)⊢ 1 ∈ spectrum ℝ A.toEnd A:SO(3)⊢ 1 ∈ spectrum ℝ A.toEnd] A:SO(3)⊢ 1 ∈ spectrum ℝ A.toEnd
erw [AlgEquiv.spectrum_eq (Matrix.toLinAlgEquiv (EuclideanSpace.basisFun (Fin 3) ℝ).toBasis) A.1 A:SO(3)⊢ 1 ∈ spectrum ℝ ↑A] A:SO(3)⊢ 1 ∈ spectrum ℝ ↑A
exact one_in_spectrum A All goals completed! 🐙
For every element of SO(3) there exists a vector which remains unchanged under the
action of that SO(3) element.
lemma exists_stationary_vec (A : SO(3)) :
∃ (v : EuclideanSpace ℝ (Fin 3)),
Orthonormal ℝ (({0} : Set (Fin 3)).restrict (fun _ => v))
∧ A.toEnd v = v := by A:SO(3)⊢ ∃ v, Orthonormal ℝ ({0}.restrict fun x => v) ∧ A.toEnd v = v
obtain ⟨v, hv⟩ := End.HasEigenvalue.exists_hasEigenvector $ one_is_eigenvalue A A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 v⊢ ∃ v, Orthonormal ℝ ({0}.restrict fun x => v) ∧ A.toEnd v = v
have hvn : ‖v‖ ≠ 0 := norm_ne_zero_iff.mpr hv.2 A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0⊢ ∃ v, Orthonormal ℝ ({0}.restrict fun x => v) ∧ A.toEnd v = v
use (1/‖v‖) • v h A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0⊢ Orthonormal ℝ ({0}.restrict fun x => (1 / ‖v‖) • v) ∧ A.toEnd ((1 / ‖v‖) • v) = (1 / ‖v‖) • v
constructor h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0⊢ Orthonormal ℝ ({0}.restrict fun x => (1 / ‖v‖) • v)h.right A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0⊢ A.toEnd ((1 / ‖v‖) • v) = (1 / ‖v‖) • v
· h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0⊢ Orthonormal ℝ ({0}.restrict fun x => (1 / ‖v‖) • v) rw [@orthonormal_iff_ite h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0⊢ ∀ (i j : ↑{0}),
inner ℝ ({0}.restrict (fun x => (1 / ‖v‖) • v) i) ({0}.restrict (fun x => (1 / ‖v‖) • v) j) = if i = j then 1 else 0 h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0⊢ ∀ (i j : ↑{0}),
inner ℝ ({0}.restrict (fun x => (1 / ‖v‖) • v) i) ({0}.restrict (fun x => (1 / ‖v‖) • v) j) = if i = j then 1 else 0] h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0⊢ ∀ (i j : ↑{0}),
inner ℝ ({0}.restrict (fun x => (1 / ‖v‖) • v) i) ({0}.restrict (fun x => (1 / ‖v‖) • v) j) = if i = j then 1 else 0
intro v1 v2 h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}v2:↑{0}⊢ inner ℝ ({0}.restrict (fun x => (1 / ‖v‖) • v) v1) ({0}.restrict (fun x => (1 / ‖v‖) • v) v2) = if v1 = v2 then 1 else 0
simp only [one_div] h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}v2:↑{0}⊢ inner ℝ ({0}.restrict (fun x => ‖v‖⁻¹ • v) v1) ({0}.restrict (fun x => ‖v‖⁻¹ • v) v2) = if v1 = v2 then 1 else 0
have hveq : v1 = v2 := by A:SO(3)⊢ ∃ v, Orthonormal ℝ ({0}.restrict fun x => v) ∧ A.toEnd v = v h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}v2:↑{0}hveq:v1 = v2⊢ inner ℝ ({0}.restrict (fun x => ‖v‖⁻¹ • v) v1) ({0}.restrict (fun x => ‖v‖⁻¹ • v) v2) = if v1 = v2 then 1 else 0 aesoph.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}v2:↑{0}hveq:v1 = v2⊢ inner ℝ ({0}.restrict (fun x => ‖v‖⁻¹ • v) v1) ({0}.restrict (fun x => ‖v‖⁻¹ • v) v2) = if v1 = v2 then 1 else 0h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}v2:↑{0}hveq:v1 = v2⊢ inner ℝ ({0}.restrict (fun x => ‖v‖⁻¹ • v) v1) ({0}.restrict (fun x => ‖v‖⁻¹ • v) v2) = if v1 = v2 then 1 else 0
subst hveq h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ inner ℝ ({0}.restrict (fun x => ‖v‖⁻¹ • v) v1) ({0}.restrict (fun x => ‖v‖⁻¹ • v) v1) = if v1 = v1 then 1 else 0
rw [Set.restrict_apply, h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ inner ℝ (‖v‖⁻¹ • v) (‖v‖⁻¹ • v) = if v1 = v1 then 1 else 0 h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ ‖v‖⁻¹ * ((starRingEnd ℝ) ‖v‖⁻¹ * ‖v‖ ^ 2) = if v1 = v1 then 1 else 0 inner_smul_right, h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ ‖v‖⁻¹ * inner ℝ (‖v‖⁻¹ • v) v = if v1 = v1 then 1 else 0h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ ‖v‖⁻¹ * ((starRingEnd ℝ) ‖v‖⁻¹ * ‖v‖ ^ 2) = if v1 = v1 then 1 else 0 inner_smul_left, h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ ‖v‖⁻¹ * ((starRingEnd ℝ) ‖v‖⁻¹ * inner ℝ v v) = if v1 = v1 then 1 else 0h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ ‖v‖⁻¹ * ((starRingEnd ℝ) ‖v‖⁻¹ * ‖v‖ ^ 2) = if v1 = v1 then 1 else 0 real_inner_self_eq_norm_sq v h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ ‖v‖⁻¹ * ((starRingEnd ℝ) ‖v‖⁻¹ * ‖v‖ ^ 2) = if v1 = v1 then 1 else 0h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ ‖v‖⁻¹ * ((starRingEnd ℝ) ‖v‖⁻¹ * ‖v‖ ^ 2) = if v1 = v1 then 1 else 0]h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ ‖v‖⁻¹ * ((starRingEnd ℝ) ‖v‖⁻¹ * ‖v‖ ^ 2) = if v1 = v1 then 1 else 0
simp only [map_inv₀, conj_trivial, Fin.isValue, ↓reduceIte] h.left A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0v1:↑{0}⊢ ‖v‖⁻¹ * (‖v‖⁻¹ * ‖v‖ ^ 2) = 1
field_simp All goals completed! 🐙
· h.right A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:A.toEnd.HasEigenvector 1 vhvn:‖v‖ ≠ 0⊢ A.toEnd ((1 / ‖v‖) • v) = (1 / ‖v‖) • v simp [End.mem_eigenspace_iff.mp hv.1] All goals completed! 🐙
For every element of SO(3) there exists a basis indexed by Fin 3 under which the first
element remains invariant.
lemma exists_basis_preserved (A : SO(3)) :
∃ (b : OrthonormalBasis (Fin 3) ℝ (EuclideanSpace ℝ (Fin 3))), A.toEnd (b 0) = b 0 := by A:SO(3)⊢ ∃ b, A.toEnd (b 0) = b 0
obtain ⟨v, hv⟩ := exists_stationary_vec A A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:Orthonormal ℝ ({0}.restrict fun x => v) ∧ A.toEnd v = v⊢ ∃ b, A.toEnd (b 0) = b 0
obtain ⟨b, hb⟩ := Orthonormal.exists_orthonormalBasis_extension_of_card_eq (by A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:Orthonormal ℝ ({0}.restrict fun x => v) ∧ A.toEnd v = v⊢ finrank ℝ (EuclideanSpace ℝ (Fin 3)) = Fintype.card (Fin 3) A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:Orthonormal ℝ ({0}.restrict fun x => v) ∧ A.toEnd v = vb:OrthonormalBasis (Fin 3) ℝ (EuclideanSpace ℝ (Fin 3))hb:∀ i ∈ {0}, b i = v⊢ ∃ b, A.toEnd (b 0) = b 0 aesop All goals completed! 🐙 A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:Orthonormal ℝ ({0}.restrict fun x => v) ∧ A.toEnd v = vb:OrthonormalBasis (Fin 3) ℝ (EuclideanSpace ℝ (Fin 3))hb:∀ i ∈ {0}, b i = v⊢ ∃ b, A.toEnd (b 0) = b 0) hv.1 A:SO(3)v:EuclideanSpace ℝ (Fin 3)hv:Orthonormal ℝ ({0}.restrict fun x => v) ∧ A.toEnd v = vb:OrthonormalBasis (Fin 3) ℝ (EuclideanSpace ℝ (Fin 3))hb:∀ i ∈ {0}, b i = v⊢ ∃ b, A.toEnd (b 0) = b 0
aesop All goals completed! 🐙