Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - chore(Analysis/InnerProductSpace): weaken assumptions to SeminormedAddCommGroup #17007

Closed
wants to merge 9 commits into from
117 changes: 53 additions & 64 deletions Mathlib/Analysis/InnerProductSpace/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1003,27 +1003,12 @@ theorem coe_basisOfOrthonormalOfCardEqFinrank [Fintype ΞΉ] [Nonempty ΞΉ] {v : ΞΉ
(basisOfOrthonormalOfCardEqFinrank hv card_eq : ΞΉ β†’ E) = v :=
coe_basisOfLinearIndependentOfCardEqFinrank _ _

end OrthonormalSets_Seminormed

section OrthonormalSets

variable [NormedAddCommGroup E] [InnerProductSpace π•œ E]
variable [NormedAddCommGroup F] [InnerProductSpace ℝ F]
variable {ΞΉ : Type*}

local notation "βŸͺ" x ", " y "⟫" => @inner π•œ _ _ x y

local notation "IK" => @RCLike.I π•œ _

local postfix:90 "†" => starRingEnd _

theorem Orthonormal.ne_zero {v : ΞΉ β†’ E} (hv : Orthonormal π•œ v) (i : ΞΉ) : v i β‰  0 := by
have : β€–v iβ€– β‰  0 := by
rw [hv.1 i]
norm_num
simpa using this
refine ne_of_apply_ne norm ?_
rw [hv.1 i, norm_zero]
norm_num

end OrthonormalSets
end OrthonormalSets_Seminormed

section Norm_Seminormed

Expand Down Expand Up @@ -1198,9 +1183,9 @@ instance (priority := 100) InnerProductSpace.toUniformConvexSpace : UniformConve
ring_nf
exact sub_le_sub_left (pow_le_pow_left hΡ.le hxy _) 4⟩

section Complex
section Complex_Seminormed

variable {V : Type*} [NormedAddCommGroup V] [InnerProductSpace β„‚ V]
variable {V : Type*} [SeminormedAddCommGroup V] [InnerProductSpace β„‚ V]

/-- A complex polarization identity, with a linear map
-/
Expand All @@ -1226,6 +1211,12 @@ theorem inner_map_polarization' (T : V β†’β‚—[β„‚] V) (x y : V) :
mul_add, ← mul_assoc, mul_neg, neg_neg, sub_neg_eq_add, one_mul, neg_one_mul, mul_sub, sub_sub]
ring

end Complex_Seminormed

section Complex

variable {V : Type*} [NormedAddCommGroup V] [InnerProductSpace β„‚ V]

/-- A linear map `T` is zero, if and only if the identity `βŸͺT x, x⟫_β„‚ = 0` holds for all `x`.
-/
theorem inner_map_self_eq_zero (T : V β†’β‚—[β„‚] V) : (βˆ€ x : V, βŸͺT x, x⟫_β„‚ = 0) ↔ T = 0 := by
Expand Down Expand Up @@ -1551,7 +1542,7 @@ variable {π•œ}

namespace ContinuousLinearMap

variable {E' : Type*} [NormedAddCommGroup E'] [InnerProductSpace π•œ E']
variable {E' : Type*} [SeminormedAddCommGroup E'] [InnerProductSpace π•œ E']

-- Note: odd and expensive build behavior is explicitly turned off using `noncomputable`
/-- Given `f : E β†’L[π•œ] E'`, construct the continuous sesquilinear form `fun x y ↦ βŸͺx, A y⟫`, given
Expand All @@ -1576,6 +1567,46 @@ theorem toSesqForm_apply_norm_le {f : E β†’L[π•œ] E'} {v : E'} : β€–toSesqForm

end ContinuousLinearMap

section

variable {ΞΉ : Type*} {ΞΉ' : Type*} {ΞΉ'' : Type*}
variable {E' : Type*} [SeminormedAddCommGroup E'] [InnerProductSpace π•œ E']
variable {E'' : Type*} [SeminormedAddCommGroup E''] [InnerProductSpace π•œ E'']

@[simp]
theorem Orthonormal.equiv_refl {v : Basis ΞΉ π•œ E} (hv : Orthonormal π•œ v) :
hv.equiv hv (Equiv.refl ΞΉ) = LinearIsometryEquiv.refl π•œ E :=
v.ext_linearIsometryEquiv fun i => by
simp only [Orthonormal.equiv_apply, Equiv.coe_refl, id, LinearIsometryEquiv.coe_refl]

@[simp]
theorem Orthonormal.equiv_symm {v : Basis ΞΉ π•œ E} (hv : Orthonormal π•œ v) {v' : Basis ΞΉ' π•œ E'}
(hv' : Orthonormal π•œ v') (e : ΞΉ ≃ ΞΉ') : (hv.equiv hv' e).symm = hv'.equiv hv e.symm :=
v'.ext_linearIsometryEquiv fun i =>
(hv.equiv hv' e).injective <| by
simp only [LinearIsometryEquiv.apply_symm_apply, Orthonormal.equiv_apply, e.apply_symm_apply]

end

variable (π•œ)

/-- `innerSL` is an isometry. Note that the associated `LinearIsometry` is defined in
`InnerProductSpace.Dual` as `toDualMap`. -/
@[simp]
theorem innerSL_apply_norm (x : E) : β€–innerSL π•œ xβ€– = β€–xβ€– := by
refine
le_antisymm ((innerSL π•œ x).opNorm_le_bound (norm_nonneg _) fun y => norm_inner_le_norm _ _) ?_
rcases (norm_nonneg x).eq_or_gt with (h | h)
Β· simp [h]
Β· refine (mul_le_mul_right h).mp ?_
calc
β€–xβ€– * β€–xβ€– = β€–(βŸͺx, x⟫ : π•œ)β€– := by
rw [← sq, inner_self_eq_norm_sq_to_K, norm_pow, norm_ofReal, abs_norm]
_ ≀ β€–innerSL π•œ xβ€– * β€–xβ€– := (innerSL π•œ x).le_opNorm _

lemma norm_innerSL_le : β€–innerSL π•œ (E := E)β€– ≀ 1 :=
ContinuousLinearMap.opNorm_le_bound _ zero_le_one (by simp)

end Norm_Seminormed

section Norm
Expand Down Expand Up @@ -1611,27 +1642,6 @@ theorem dist_div_norm_sq_smul {x y : F} (hx : x β‰  0) (hy : y β‰  0) (R : ℝ)
_ = R ^ 2 / (β€–xβ€– * β€–yβ€–) * dist x y := by
rw [sqrt_mul, sqrt_sq, sqrt_sq, dist_eq_norm] <;> positivity

section

variable {ΞΉ : Type*} {ΞΉ' : Type*} {ΞΉ'' : Type*}
variable {E' : Type*} [NormedAddCommGroup E'] [InnerProductSpace π•œ E']
variable {E'' : Type*} [NormedAddCommGroup E''] [InnerProductSpace π•œ E'']

@[simp]
theorem Orthonormal.equiv_refl {v : Basis ΞΉ π•œ E} (hv : Orthonormal π•œ v) :
hv.equiv hv (Equiv.refl ΞΉ) = LinearIsometryEquiv.refl π•œ E :=
v.ext_linearIsometryEquiv fun i => by
simp only [Orthonormal.equiv_apply, Equiv.coe_refl, id, LinearIsometryEquiv.coe_refl]

@[simp]
theorem Orthonormal.equiv_symm {v : Basis ΞΉ π•œ E} (hv : Orthonormal π•œ v) {v' : Basis ΞΉ' π•œ E'}
(hv' : Orthonormal π•œ v') (e : ΞΉ ≃ ΞΉ') : (hv.equiv hv' e).symm = hv'.equiv hv e.symm :=
v'.ext_linearIsometryEquiv fun i =>
(hv.equiv hv' e).injective <| by
simp only [LinearIsometryEquiv.apply_symm_apply, Orthonormal.equiv_apply, e.apply_symm_apply]

end

/-- The inner product of a nonzero vector with a nonzero multiple of
itself, divided by the product of their norms, has absolute value
1. -/
Expand Down Expand Up @@ -1819,27 +1829,6 @@ theorem inner_sum_smul_sum_smul_of_sum_eq_zero {ι₁ : Type*} {s₁ : Finset ΞΉ
mul_zero, Finset.sum_const_zero, zero_add, zero_sub, Finset.mul_sum, neg_div,
Finset.sum_div, mul_div_assoc, mul_assoc]

variable (π•œ)

/-- `innerSL` is an isometry. Note that the associated `LinearIsometry` is defined in
`InnerProductSpace.Dual` as `toDualMap`. -/
@[simp]
theorem innerSL_apply_norm (x : E) : β€–innerSL π•œ xβ€– = β€–xβ€– := by
refine
le_antisymm ((innerSL π•œ x).opNorm_le_bound (norm_nonneg _) fun y => norm_inner_le_norm _ _) ?_
rcases eq_or_ne x 0 with (rfl | h)
Β· simp
Β· refine (mul_le_mul_right (norm_pos_iff.2 h)).mp ?_
calc
β€–xβ€– * β€–xβ€– = β€–(βŸͺx, x⟫ : π•œ)β€– := by
rw [← sq, inner_self_eq_norm_sq_to_K, norm_pow, norm_ofReal, abs_norm]
_ ≀ β€–innerSL π•œ xβ€– * β€–xβ€– := (innerSL π•œ x).le_opNorm _

lemma norm_innerSL_le : β€–innerSL π•œ (E := E)β€– ≀ 1 :=
ContinuousLinearMap.opNorm_le_bound _ zero_le_one (by simp)

variable {π•œ}

/-- When an inner product space `E` over `π•œ` is considered as a real normed space, its inner
product satisfies `IsBoundedBilinearMap`.
j-loreaux marked this conversation as resolved.
Show resolved Hide resolved

Expand Down
100 changes: 60 additions & 40 deletions Mathlib/Analysis/InnerProductSpace/Symmetric.lean
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ open RCLike

open ComplexConjugate

section Seminormed

variable {π•œ E E' F G : Type*} [RCLike π•œ]
variable [NormedAddCommGroup E] [InnerProductSpace π•œ E]
variable [NormedAddCommGroup F] [InnerProductSpace π•œ F]
variable [NormedAddCommGroup G] [InnerProductSpace π•œ G]
variable [NormedAddCommGroup E'] [InnerProductSpace ℝ E']
variable [SeminormedAddCommGroup E] [InnerProductSpace π•œ E]
variable [SeminormedAddCommGroup F] [InnerProductSpace π•œ F]
variable [SeminormedAddCommGroup G] [InnerProductSpace π•œ G]
variable [SeminormedAddCommGroup E'] [InnerProductSpace ℝ E']

local notation "βŸͺ" x ", " y "⟫" => @inner π•œ _ _ x y

Expand Down Expand Up @@ -83,6 +85,57 @@ theorem IsSymmetric.add {T S : E β†’β‚—[π•œ] E} (hT : T.IsSymmetric) (hS : S.Is
rw [LinearMap.add_apply, inner_add_left, hT x y, hS x y, ← inner_add_right]
rfl

/-- For a symmetric operator `T`, the function `fun x ↦ βŸͺT x, x⟫` is real-valued. -/
@[simp]
theorem IsSymmetric.coe_reApplyInnerSelf_apply {T : E β†’L[π•œ] E} (hT : IsSymmetric (T : E β†’β‚—[π•œ] E))
(x : E) : (T.reApplyInnerSelf x : π•œ) = βŸͺT x, x⟫ := by
rsuffices ⟨r, hr⟩ : βˆƒ r : ℝ, βŸͺT x, x⟫ = r
Β· simp [hr, T.reApplyInnerSelf_apply]
rw [← conj_eq_iff_real]
exact hT.conj_inner_sym x x

/-- If a symmetric operator preserves a submodule, its restriction to that submodule is
symmetric. -/
theorem IsSymmetric.restrict_invariant {T : E β†’β‚—[π•œ] E} (hT : IsSymmetric T) {V : Submodule π•œ E}
(hV : βˆ€ v ∈ V, T v ∈ V) : IsSymmetric (T.restrict hV) := fun v w => hT v w

/-- Polarization identity for symmetric linear maps.
See `inner_map_polarization` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_polarization {T : E β†’β‚—[π•œ] E} (hT : T.IsSymmetric) (x y : E) :
βŸͺT x, y⟫ =
(βŸͺT (x + y), x + y⟫ - βŸͺT (x - y), x - y⟫ - I * βŸͺT (x + (I : π•œ) β€’ y), x + (I : π•œ) β€’ y⟫ +
I * βŸͺT (x - (I : π•œ) β€’ y), x - (I : π•œ) β€’ y⟫) /
4 := by
rcases@I_mul_I_ax π•œ _ with (h | h)
Β· simp_rw [h, zero_mul, sub_zero, add_zero, map_add, map_sub, inner_add_left,
inner_add_right, inner_sub_left, inner_sub_right, hT x, ← inner_conj_symm x (T y)]
suffices (re βŸͺT y, x⟫ : π•œ) = βŸͺT y, x⟫ by
rw [conj_eq_iff_re.mpr this]
ring
rw [← re_add_im βŸͺT y, x⟫]
simp_rw [h, mul_zero, add_zero]
norm_cast
Β· simp_rw [map_add, map_sub, inner_add_left, inner_add_right, inner_sub_left, inner_sub_right,
LinearMap.map_smul, inner_smul_left, inner_smul_right, RCLike.conj_I, mul_add, mul_sub,
sub_sub, ← mul_assoc, mul_neg, h, neg_neg, one_mul, neg_one_mul]
ring

end LinearMap

end Seminormed

section Normed

variable {π•œ E E' F G : Type*} [RCLike π•œ]
variable [NormedAddCommGroup E] [InnerProductSpace π•œ E]
variable [NormedAddCommGroup F] [InnerProductSpace π•œ F]
variable [NormedAddCommGroup G] [InnerProductSpace π•œ G]
variable [NormedAddCommGroup E'] [InnerProductSpace ℝ E']

local notation "βŸͺ" x ", " y "⟫" => @inner π•œ _ _ x y

namespace LinearMap

/-- The **Hellinger--Toeplitz theorem**: if a symmetric operator is defined on a complete space,
then it is automatically continuous. -/
theorem IsSymmetric.continuous [CompleteSpace E] {T : E β†’β‚—[π•œ] E} (hT : IsSymmetric T) :
Expand All @@ -100,20 +153,6 @@ theorem IsSymmetric.continuous [CompleteSpace E] {T : E β†’β‚—[π•œ] E} (hT : Is
rw [← sub_self x]
exact hu.sub_const _

/-- For a symmetric operator `T`, the function `fun x ↦ βŸͺT x, x⟫` is real-valued. -/
@[simp]
theorem IsSymmetric.coe_reApplyInnerSelf_apply {T : E β†’L[π•œ] E} (hT : IsSymmetric (T : E β†’β‚—[π•œ] E))
(x : E) : (T.reApplyInnerSelf x : π•œ) = βŸͺT x, x⟫ := by
rsuffices ⟨r, hr⟩ : βˆƒ r : ℝ, βŸͺT x, x⟫ = r
Β· simp [hr, T.reApplyInnerSelf_apply]
rw [← conj_eq_iff_real]
exact hT.conj_inner_sym x x

/-- If a symmetric operator preserves a submodule, its restriction to that submodule is
symmetric. -/
theorem IsSymmetric.restrict_invariant {T : E β†’β‚—[π•œ] E} (hT : IsSymmetric T) {V : Submodule π•œ E}
(hV : βˆ€ v ∈ V, T v ∈ V) : IsSymmetric (T.restrict hV) := fun v w => hT v w

theorem IsSymmetric.restrictScalars {T : E β†’β‚—[π•œ] E} (hT : T.IsSymmetric) :
@LinearMap.IsSymmetric ℝ E _ _ (InnerProductSpace.rclikeToReal π•œ E)
(@LinearMap.restrictScalars ℝ π•œ _ _ _ _ _ _ (InnerProductSpace.rclikeToReal π•œ E).toModule
Expand All @@ -122,7 +161,7 @@ theorem IsSymmetric.restrictScalars {T : E β†’β‚—[π•œ] E} (hT : T.IsSymmetric)

section Complex

variable {V : Type*} [NormedAddCommGroup V] [InnerProductSpace β„‚ V]
variable {V : Type*} [SeminormedAddCommGroup V] [InnerProductSpace β„‚ V]

attribute [local simp] map_ofNat in -- use `ofNat` simp theorem with bad keys
open scoped InnerProductSpace in
Expand All @@ -146,27 +185,6 @@ theorem isSymmetric_iff_inner_map_self_real (T : V β†’β‚—[β„‚] V) :

end Complex

/-- Polarization identity for symmetric linear maps.
See `inner_map_polarization` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_polarization {T : E β†’β‚—[π•œ] E} (hT : T.IsSymmetric) (x y : E) :
βŸͺT x, y⟫ =
(βŸͺT (x + y), x + y⟫ - βŸͺT (x - y), x - y⟫ - I * βŸͺT (x + (I : π•œ) β€’ y), x + (I : π•œ) β€’ y⟫ +
I * βŸͺT (x - (I : π•œ) β€’ y), x - (I : π•œ) β€’ y⟫) /
4 := by
rcases@I_mul_I_ax π•œ _ with (h | h)
Β· simp_rw [h, zero_mul, sub_zero, add_zero, map_add, map_sub, inner_add_left,
inner_add_right, inner_sub_left, inner_sub_right, hT x, ← inner_conj_symm x (T y)]
suffices (re βŸͺT y, x⟫ : π•œ) = βŸͺT y, x⟫ by
rw [conj_eq_iff_re.mpr this]
ring
rw [← re_add_im βŸͺT y, x⟫]
simp_rw [h, mul_zero, add_zero]
norm_cast
Β· simp_rw [map_add, map_sub, inner_add_left, inner_add_right, inner_sub_left, inner_sub_right,
LinearMap.map_smul, inner_smul_left, inner_smul_right, RCLike.conj_I, mul_add, mul_sub,
sub_sub, ← mul_assoc, mul_neg, h, neg_neg, one_mul, neg_one_mul]
ring

/-- A symmetric linear map `T` is zero if and only if `βŸͺT x, x⟫_ℝ = 0` for all `x`.
See `inner_map_self_eq_zero` for the complex version without the symmetric assumption. -/
theorem IsSymmetric.inner_map_self_eq_zero {T : E β†’β‚—[π•œ] E} (hT : T.IsSymmetric) :
Expand All @@ -178,3 +196,5 @@ theorem IsSymmetric.inner_map_self_eq_zero {T : E β†’β‚—[π•œ] E} (hT : T.IsSymm
ring

end LinearMap

end Normed
Loading