From 682303903cf9f85d068aba381ce337a3d6db01cd Mon Sep 17 00:00:00 2001 From: Yoh Tanimoto <57562556+yoh-tanimoto@users.noreply.github.com> Date: Sat, 21 Sep 2024 22:23:18 +0200 Subject: [PATCH 1/8] Update Basic.lean --- Mathlib/Analysis/InnerProductSpace/Basic.lean | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index 2e4adbdbee16f..cca56e4d1fe41 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -1198,9 +1198,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 -/ @@ -1226,6 +1226,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 @@ -1551,7 +1557,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 From 94fe59e1b2a807158344426392c5e570e49eca40 Mon Sep 17 00:00:00 2001 From: Yoh Tanimoto <57562556+yoh-tanimoto@users.noreply.github.com> Date: Sat, 21 Sep 2024 22:24:13 +0200 Subject: [PATCH 2/8] Update Symmetric.lean --- .../Analysis/InnerProductSpace/Symmetric.lean | 100 +++++++++++------- 1 file changed, 60 insertions(+), 40 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean index 4928bc0cac733..b458a7cf6cfb0 100644 --- a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean +++ b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean @@ -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 @@ -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) : @@ -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 @@ -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 @@ -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) : @@ -178,3 +196,5 @@ theorem IsSymmetric.inner_map_self_eq_zero {T : E →ₗ[𝕜] E} (hT : T.IsSymm ring end LinearMap + +end Normed From 3df8261c39401738d68fd112ce7a5f5886746f49 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sun, 22 Sep 2024 00:10:04 +0000 Subject: [PATCH 3/8] some more --- Mathlib/Analysis/InnerProductSpace/Basic.lean | 105 ++++++++---------- 1 file changed, 44 insertions(+), 61 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index cca56e4d1fe41..3cfdd3ae95467 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -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 @@ -1582,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 @@ -1617,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. -/ @@ -1825,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`. From e4280c42b8547f3c82ec53d59d59c476cb8f419a Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Mon, 23 Sep 2024 13:05:32 +0000 Subject: [PATCH 4/8] more generalizations --- Mathlib/Analysis/InnerProductSpace/Basic.lean | 79 ++++++++++--------- .../Analysis/Normed/Module/Completion.lean | 2 +- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index 3cfdd3ae95467..65b8388ad2719 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -1607,6 +1607,41 @@ theorem innerSL_apply_norm (x : E) : ‖innerSL 𝕜 x‖ = ‖x‖ := by lemma norm_innerSL_le : ‖innerSL 𝕜 (E := E)‖ ≤ 1 := ContinuousLinearMap.opNorm_le_bound _ zero_le_one (by simp) +/-- When an inner product space `E` over `𝕜` is considered as a real normed space, its inner +product satisfies `IsBoundedBilinearMap`. + +In order to state these results, we need a `NormedSpace ℝ E` instance. We will later establish +such an instance by restriction-of-scalars, `InnerProductSpace.rclikeToReal 𝕜 E`, but this +instance may be not definitionally equal to some other “natural” instance. So, we assume +`[NormedSpace ℝ E]`. +-/ +theorem _root_.isBoundedBilinearMap_inner [NormedSpace ℝ E] [IsScalarTower ℝ 𝕜 E] : + IsBoundedBilinearMap ℝ fun p : E × E => ⟪p.1, p.2⟫ := + { add_left := inner_add_left + smul_left := fun r x y => by + simp only [← algebraMap_smul 𝕜 r x, algebraMap_eq_ofReal, inner_smul_real_left] + add_right := inner_add_right + smul_right := fun r x y => by + simp only [← algebraMap_smul 𝕜 r y, algebraMap_eq_ofReal, inner_smul_real_right] + bound := + ⟨1, zero_lt_one, fun x y => by + rw [one_mul] + exact norm_inner_le_norm x y⟩ } + +/-- The inner product of two weighted sums, where the weights in each +sum add to 0, in terms of the norms of pairwise differences. -/ +theorem inner_sum_smul_sum_smul_of_sum_eq_zero {ι₁ : Type*} {s₁ : Finset ι₁} {w₁ : ι₁ → ℝ} + (v₁ : ι₁ → F) (h₁ : ∑ i ∈ s₁, w₁ i = 0) {ι₂ : Type*} {s₂ : Finset ι₂} {w₂ : ι₂ → ℝ} + (v₂ : ι₂ → F) (h₂ : ∑ i ∈ s₂, w₂ i = 0) : + ⟪∑ i₁ ∈ s₁, w₁ i₁ • v₁ i₁, ∑ i₂ ∈ s₂, w₂ i₂ • v₂ i₂⟫_ℝ = + (-∑ i₁ ∈ s₁, ∑ i₂ ∈ s₂, w₁ i₁ * w₂ i₂ * (‖v₁ i₁ - v₂ i₂‖ * ‖v₁ i₁ - v₂ i₂‖)) / 2 := by + simp_rw [sum_inner, inner_sum, real_inner_smul_left, real_inner_smul_right, + real_inner_eq_norm_mul_self_add_norm_mul_self_sub_norm_sub_mul_self_div_two, ← div_sub_div_same, + ← div_add_div_same, mul_sub_left_distrib, left_distrib, Finset.sum_sub_distrib, + Finset.sum_add_distrib, ← Finset.mul_sum, ← Finset.sum_mul, h₁, h₂, zero_mul, + mul_zero, Finset.sum_const_zero, zero_add, zero_sub, Finset.mul_sum, neg_div, + Finset.sum_div, mul_div_assoc, mul_assoc] + end Norm_Seminormed section Norm @@ -1815,41 +1850,6 @@ theorem eq_of_norm_le_re_inner_eq_norm_sq {x y : E} (hle : ‖x‖ ≤ ‖y‖) have H₂ : re ⟪y, x⟫ = ‖y‖ ^ 2 := by rwa [← inner_conj_symm, conj_re] simpa [inner_sub_left, inner_sub_right, ← norm_sq_eq_inner, h, H₂] using H₁ -/-- The inner product of two weighted sums, where the weights in each -sum add to 0, in terms of the norms of pairwise differences. -/ -theorem inner_sum_smul_sum_smul_of_sum_eq_zero {ι₁ : Type*} {s₁ : Finset ι₁} {w₁ : ι₁ → ℝ} - (v₁ : ι₁ → F) (h₁ : ∑ i ∈ s₁, w₁ i = 0) {ι₂ : Type*} {s₂ : Finset ι₂} {w₂ : ι₂ → ℝ} - (v₂ : ι₂ → F) (h₂ : ∑ i ∈ s₂, w₂ i = 0) : - ⟪∑ i₁ ∈ s₁, w₁ i₁ • v₁ i₁, ∑ i₂ ∈ s₂, w₂ i₂ • v₂ i₂⟫_ℝ = - (-∑ i₁ ∈ s₁, ∑ i₂ ∈ s₂, w₁ i₁ * w₂ i₂ * (‖v₁ i₁ - v₂ i₂‖ * ‖v₁ i₁ - v₂ i₂‖)) / 2 := by - simp_rw [sum_inner, inner_sum, real_inner_smul_left, real_inner_smul_right, - real_inner_eq_norm_mul_self_add_norm_mul_self_sub_norm_sub_mul_self_div_two, ← div_sub_div_same, - ← div_add_div_same, mul_sub_left_distrib, left_distrib, Finset.sum_sub_distrib, - Finset.sum_add_distrib, ← Finset.mul_sum, ← Finset.sum_mul, h₁, h₂, zero_mul, - mul_zero, Finset.sum_const_zero, zero_add, zero_sub, Finset.mul_sum, neg_div, - Finset.sum_div, mul_div_assoc, mul_assoc] - -/-- When an inner product space `E` over `𝕜` is considered as a real normed space, its inner -product satisfies `IsBoundedBilinearMap`. - -In order to state these results, we need a `NormedSpace ℝ E` instance. We will later establish -such an instance by restriction-of-scalars, `InnerProductSpace.rclikeToReal 𝕜 E`, but this -instance may be not definitionally equal to some other “natural” instance. So, we assume -`[NormedSpace ℝ E]`. --/ -theorem _root_.isBoundedBilinearMap_inner [NormedSpace ℝ E] : - IsBoundedBilinearMap ℝ fun p : E × E => ⟪p.1, p.2⟫ := - { add_left := inner_add_left - smul_left := fun r x y => by - simp only [← algebraMap_smul 𝕜 r x, algebraMap_eq_ofReal, inner_smul_real_left] - add_right := inner_add_right - smul_right := fun r x y => by - simp only [← algebraMap_smul 𝕜 r y, algebraMap_eq_ofReal, inner_smul_real_right] - bound := - ⟨1, zero_lt_one, fun x y => by - rw [one_mul] - exact norm_inner_le_norm x y⟩ } - end Norm section BesselsInequality @@ -2258,7 +2258,7 @@ end RCLikeToReal section Continuous -variable [NormedAddCommGroup E] [InnerProductSpace 𝕜 E] +variable [SeminormedAddCommGroup E] [InnerProductSpace 𝕜 E] local notation "⟪" x ", " y "⟫" => @inner 𝕜 _ _ x y @@ -2273,7 +2273,8 @@ local postfix:90 "†" => starRingEnd _ theorem continuous_inner : Continuous fun p : E × E => ⟪p.1, p.2⟫ := letI : InnerProductSpace ℝ E := InnerProductSpace.rclikeToReal 𝕜 E - isBoundedBilinearMap_inner.continuous + letI : IsScalarTower ℝ 𝕜 E := RestrictScalars.isScalarTower _ _ _ + (isBoundedBilinearMap_inner 𝕜).continuous variable {α : Type*} @@ -2323,7 +2324,7 @@ end ReApplyInnerSelf section ReApplyInnerSelf_Seminormed -variable [NormedAddCommGroup E] [InnerProductSpace 𝕜 E] +variable [SeminormedAddCommGroup E] [InnerProductSpace 𝕜 E] local notation "⟪" x ", " y "⟫" => @inner 𝕜 _ _ x y @@ -2345,7 +2346,7 @@ end ReApplyInnerSelf_Seminormed section UniformSpace.Completion -variable [NormedAddCommGroup E] [InnerProductSpace 𝕜 E] +variable [SeminormedAddCommGroup E] [InnerProductSpace 𝕜 E] local notation "⟪" x ", " y "⟫" => @inner 𝕜 _ _ x y diff --git a/Mathlib/Analysis/Normed/Module/Completion.lean b/Mathlib/Analysis/Normed/Module/Completion.lean index 451aed37e833c..bb143e6302377 100644 --- a/Mathlib/Analysis/Normed/Module/Completion.lean +++ b/Mathlib/Analysis/Normed/Module/Completion.lean @@ -27,7 +27,7 @@ namespace UniformSpace namespace Completion -variable (𝕜 E : Type*) [NormedField 𝕜] [NormedAddCommGroup E] [NormedSpace 𝕜 E] +variable (𝕜 E : Type*) [NormedField 𝕜] [SeminormedAddCommGroup E] [NormedSpace 𝕜 E] instance (priority := 100) NormedSpace.to_uniformContinuousConstSMul : UniformContinuousConstSMul 𝕜 E := From 1e149b0f85e1409ea5e815f11639551293fd10c5 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Mon, 23 Sep 2024 21:22:03 +0000 Subject: [PATCH 5/8] revert accidental variable explicitification --- Mathlib/Analysis/InnerProductSpace/Basic.lean | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index 65b8388ad2719..d1aae79dadb37 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -1607,6 +1607,8 @@ theorem innerSL_apply_norm (x : E) : ‖innerSL 𝕜 x‖ = ‖x‖ := by 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`. From 0bfdd81d09af3ebb88807be75bb92edd5bb74885 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Mon, 23 Sep 2024 21:55:40 +0000 Subject: [PATCH 6/8] fix --- Mathlib/Analysis/InnerProductSpace/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Basic.lean b/Mathlib/Analysis/InnerProductSpace/Basic.lean index d1aae79dadb37..43030872487bc 100644 --- a/Mathlib/Analysis/InnerProductSpace/Basic.lean +++ b/Mathlib/Analysis/InnerProductSpace/Basic.lean @@ -2276,7 +2276,7 @@ local postfix:90 "†" => starRingEnd _ theorem continuous_inner : Continuous fun p : E × E => ⟪p.1, p.2⟫ := letI : InnerProductSpace ℝ E := InnerProductSpace.rclikeToReal 𝕜 E letI : IsScalarTower ℝ 𝕜 E := RestrictScalars.isScalarTower _ _ _ - (isBoundedBilinearMap_inner 𝕜).continuous + isBoundedBilinearMap_inner.continuous variable {α : Type*} From e5efd2d6c8e8f371fc3467a1074b6edef6c850fa Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Mon, 23 Sep 2024 22:46:38 +0000 Subject: [PATCH 7/8] Address the restrictScalars issue --- .../Analysis/InnerProductSpace/Symmetric.lean | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean index b458a7cf6cfb0..b661fc478cb01 100644 --- a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean +++ b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean @@ -99,6 +99,12 @@ 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) : + letI := InnerProductSpace.rclikeToReal 𝕜 E + letI : IsScalarTower ℝ 𝕜 E := RestrictScalars.isScalarTower _ _ _ + (T.restrictScalars ℝ).IsSymmetric := + fun x y => by simp [hT x y, real_inner_eq_re_inner, LinearMap.coe_restrictScalars ℝ] + /-- 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) : @@ -120,6 +126,32 @@ theorem IsSymmetric.inner_map_polarization {T : E →ₗ[𝕜] E} (hT : T.IsSymm sub_sub, ← mul_assoc, mul_neg, h, neg_neg, one_mul, neg_one_mul] ring +section Complex + +variable {V : Type*} [SeminormedAddCommGroup V] [InnerProductSpace ℂ V] + +attribute [local simp] map_ofNat in -- use `ofNat` simp theorem with bad keys +open scoped InnerProductSpace in +/-- A linear operator on a complex inner product space is symmetric precisely when +`⟪T v, v⟫_ℂ` is real for all v. -/ +theorem isSymmetric_iff_inner_map_self_real (T : V →ₗ[ℂ] V) : + IsSymmetric T ↔ ∀ v : V, conj ⟪T v, v⟫_ℂ = ⟪T v, v⟫_ℂ := by + constructor + · intro hT v + apply IsSymmetric.conj_inner_sym hT + · intro h x y + rw [← inner_conj_symm x (T y)] + rw [inner_map_polarization T x y] + simp only [starRingEnd_apply, star_div', star_sub, star_add, star_mul] + simp only [← starRingEnd_apply] + rw [h (x + y), h (x - y), h (x + Complex.I • y), h (x - Complex.I • y)] + simp only [Complex.conj_I] + rw [inner_map_polarization'] + norm_num + ring + +end Complex + end LinearMap end Seminormed @@ -153,38 +185,6 @@ theorem IsSymmetric.continuous [CompleteSpace E] {T : E →ₗ[𝕜] E} (hT : Is rw [← sub_self x] exact hu.sub_const _ -theorem IsSymmetric.restrictScalars {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) : - @LinearMap.IsSymmetric ℝ E _ _ (InnerProductSpace.rclikeToReal 𝕜 E) - (@LinearMap.restrictScalars ℝ 𝕜 _ _ _ _ _ _ (InnerProductSpace.rclikeToReal 𝕜 E).toModule - (InnerProductSpace.rclikeToReal 𝕜 E).toModule _ _ _ T) := - fun x y => by simp [hT x y, real_inner_eq_re_inner, LinearMap.coe_restrictScalars ℝ] - -section Complex - -variable {V : Type*} [SeminormedAddCommGroup V] [InnerProductSpace ℂ V] - -attribute [local simp] map_ofNat in -- use `ofNat` simp theorem with bad keys -open scoped InnerProductSpace in -/-- A linear operator on a complex inner product space is symmetric precisely when -`⟪T v, v⟫_ℂ` is real for all v. -/ -theorem isSymmetric_iff_inner_map_self_real (T : V →ₗ[ℂ] V) : - IsSymmetric T ↔ ∀ v : V, conj ⟪T v, v⟫_ℂ = ⟪T v, v⟫_ℂ := by - constructor - · intro hT v - apply IsSymmetric.conj_inner_sym hT - · intro h x y - rw [← inner_conj_symm x (T y)] - rw [inner_map_polarization T x y] - simp only [starRingEnd_apply, star_div', star_sub, star_add, star_mul] - simp only [← starRingEnd_apply] - rw [h (x + y), h (x - y), h (x + Complex.I • y), h (x - Complex.I • y)] - simp only [Complex.conj_I] - rw [inner_map_polarization'] - norm_num - ring - -end Complex - /-- 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) : From 0f88afc31f0d03b53d2f49c5efaab2905726f69f Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Mon, 23 Sep 2024 22:47:29 +0000 Subject: [PATCH 8/8] reduce diff --- .../Analysis/InnerProductSpace/Symmetric.lean | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean index b661fc478cb01..0dafa0de1b246 100644 --- a/Mathlib/Analysis/InnerProductSpace/Symmetric.lean +++ b/Mathlib/Analysis/InnerProductSpace/Symmetric.lean @@ -105,27 +105,6 @@ theorem IsSymmetric.restrictScalars {T : E →ₗ[𝕜] E} (hT : T.IsSymmetric) (T.restrictScalars ℝ).IsSymmetric := fun x y => by simp [hT x y, real_inner_eq_re_inner, LinearMap.coe_restrictScalars ℝ] -/-- 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 - section Complex variable {V : Type*} [SeminormedAddCommGroup V] [InnerProductSpace ℂ V] @@ -152,6 +131,27 @@ 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 + end LinearMap end Seminormed