From aa1dbeab548d61bc840a099abae4437046eaaf00 Mon Sep 17 00:00:00 2001 From: "Yury G. Kudryashov" Date: Thu, 4 May 2023 03:36:49 +0000 Subject: [PATCH] chore(analysis/normed_space/extend): golf, add aux lemmas (#18927) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add `linear_map.extend_to_π•œ'_apply_re`, `linear_map.sq_norm_extend_to_π•œ'_apply`, `continuous_linear_map.norm_extend_to_π•œ`, and `continuous_linear_map.norm_extend_to_π•œ'`. * Rename `norm_bound` to `continuous_linear_map.norm_extend_to_π•œ'_bound`. * Golf, use `namespace`s. --- src/analysis/normed_space/extend.lean | 89 ++++++++++--------- .../normed_space/hahn_banach/extension.lean | 2 +- 2 files changed, 47 insertions(+), 44 deletions(-) diff --git a/src/analysis/normed_space/extend.lean b/src/analysis/normed_space/extend.lean index f0a198fc8ed45..bc01ce94c0d2b 100644 --- a/src/analysis/normed_space/extend.lean +++ b/src/analysis/normed_space/extend.lean @@ -32,14 +32,17 @@ Alternate forms which operate on `[is_scalar_tower ℝ π•œ F]` instead are prov -/ open is_R_or_C +open_locale complex_conjugate variables {π•œ : Type*} [is_R_or_C π•œ] {F : Type*} [seminormed_add_comm_group F] [normed_space π•œ F] -local notation `absπ•œ` := @is_R_or_C.abs π•œ _ + +namespace linear_map + +variables [module ℝ F] [is_scalar_tower ℝ π•œ F] /-- Extend `fr : F β†’β‚—[ℝ] ℝ` to `F β†’β‚—[π•œ] π•œ` in a way that will also be continuous and have its norm bounded by `β€–frβ€–` if `fr` is continuous. -/ -noncomputable def linear_map.extend_to_π•œ' - [module ℝ F] [is_scalar_tower ℝ π•œ F] (fr : F β†’β‚—[ℝ] ℝ) : F β†’β‚—[π•œ] π•œ := +noncomputable def extend_to_π•œ' (fr : F β†’β‚—[ℝ] ℝ) : F β†’β‚—[π•œ] π•œ := begin let fc : F β†’ π•œ := Ξ» x, (fr x : π•œ) - (I : π•œ) * (fr ((I : π•œ) β€’ x)), have add : βˆ€ x y : F, fc (x + y) = fc x + fc y, @@ -73,61 +76,57 @@ begin exact { to_fun := fc, map_add' := add, map_smul' := smul_π•œ } end -lemma linear_map.extend_to_π•œ'_apply [module ℝ F] [is_scalar_tower ℝ π•œ F] - (fr : F β†’β‚—[ℝ] ℝ) (x : F) : +lemma extend_to_π•œ'_apply (fr : F β†’β‚—[ℝ] ℝ) (x : F) : fr.extend_to_π•œ' x = (fr x : π•œ) - (I : π•œ) * fr ((I : π•œ) β€’ x) := rfl +@[simp] lemma extend_to_π•œ'_apply_re (fr : F β†’β‚—[ℝ] ℝ) (x : F) : re (fr.extend_to_π•œ' x : π•œ) = fr x := +by simp only [extend_to_π•œ'_apply, map_sub, zero_mul, mul_zero, sub_zero] with is_R_or_C_simps + +lemma norm_extend_to_π•œ'_apply_sq (f : F β†’β‚—[ℝ] ℝ) (x : F) : + β€–(f.extend_to_π•œ' x : π•œ)β€– ^ 2 = f (conj (f.extend_to_π•œ' x : π•œ) β€’ x) := +calc β€–(f.extend_to_π•œ' x : π•œ)β€– ^ 2 = re (conj (f.extend_to_π•œ' x) * f.extend_to_π•œ' x : π•œ) : + by rw [is_R_or_C.conj_mul_eq_norm_sq_left, norm_sq_eq_def', of_real_re] +... = f (conj (f.extend_to_π•œ' x : π•œ) β€’ x) : + by rw [← smul_eq_mul, ← map_smul, extend_to_π•œ'_apply_re] + +end linear_map + +namespace continuous_linear_map + +variables [normed_space ℝ F] [is_scalar_tower ℝ π•œ F] + /-- The norm of the extension is bounded by `β€–frβ€–`. -/ -lemma norm_bound [normed_space ℝ F] [is_scalar_tower ℝ π•œ F] (fr : F β†’L[ℝ] ℝ) (x : F) : +lemma norm_extend_to_π•œ'_bound (fr : F β†’L[ℝ] ℝ) (x : F) : β€–(fr.to_linear_map.extend_to_π•œ' x : π•œ)β€– ≀ β€–frβ€– * β€–xβ€– := begin - let lm : F β†’β‚—[π•œ] π•œ := fr.to_linear_map.extend_to_π•œ', - -- We aim to find a `t : π•œ` such that - -- * `lm (t β€’ x) = fr (t β€’ x)` (so `lm (t β€’ x) = t * lm x ∈ ℝ`) - -- * `β€–lm xβ€– = β€–lm (t β€’ x)β€–` (so `t.abs` must be 1) - -- If `lm x β‰  0`, `(lm x)⁻¹` satisfies the first requirement, and after normalizing, it - -- satisfies the second. - -- (If `lm x = 0`, the goal is trivial.) + set lm : F β†’β‚—[π•œ] π•œ := fr.to_linear_map.extend_to_π•œ', classical, by_cases h : lm x = 0, { rw [h, norm_zero], apply mul_nonneg; exact norm_nonneg _ }, - let fx := (lm x)⁻¹, - let t := fx / (absπ•œ fx : π•œ), - have ht : absπ•œ t = 1, by field_simp [abs_of_real, of_real_inv, is_R_or_C.abs_inv, - is_R_or_C.abs_div, is_R_or_C.abs_abs, h], - have h1 : (fr (t β€’ x) : π•œ) = lm (t β€’ x), - { apply ext, - { simp only [lm, of_real_re, linear_map.extend_to_π•œ'_apply, mul_re, I_re, of_real_im, zero_mul, - add_monoid_hom.map_sub, sub_zero, mul_zero], - refl }, - { symmetry, - calc im (lm (t β€’ x)) - = im (t * lm x) : by rw [lm.map_smul, smul_eq_mul] - ... = im ((lm x)⁻¹ / (absπ•œ (lm x)⁻¹) * lm x) : rfl - ... = im (1 / (absπ•œ (lm x)⁻¹ : π•œ)) : by rw [div_mul_eq_mul_div, inv_mul_cancel h] - ... = 0 : by rw [← of_real_one, ← of_real_div, of_real_im] - ... = im (fr (t β€’ x) : π•œ) : by rw [of_real_im] } }, - calc β€–lm xβ€– = absπ•œ t * β€–lm xβ€– : by rw [ht, one_mul] - ... = β€–t * lm xβ€– : by rw [← norm_eq_abs, norm_mul] - ... = β€–lm (t β€’ x)β€– : by rw [←smul_eq_mul, lm.map_smul] - ... = β€–(fr (t β€’ x) : π•œ)β€– : by rw h1 - ... = β€–fr (t β€’ x)β€– : by rw [norm_eq_abs, abs_of_real, norm_eq_abs, abs_to_real] - ... ≀ β€–frβ€– * β€–t β€’ xβ€– : continuous_linear_map.le_op_norm _ _ - ... = β€–frβ€– * (β€–tβ€– * β€–xβ€–) : by rw norm_smul - ... ≀ β€–frβ€– * β€–xβ€– : by rw [norm_eq_abs, ht, one_mul] + rw [← mul_le_mul_left (norm_pos_iff.2 h), ← sq], + calc β€–lm xβ€– ^ 2 = fr (conj (lm x : π•œ) β€’ x) : fr.to_linear_map.norm_extend_to_π•œ'_apply_sq x + ... ≀ β€–fr (conj (lm x : π•œ) β€’ x)β€– : le_abs_self _ + ... ≀ β€–frβ€– * β€–conj (lm x : π•œ) β€’ xβ€– : le_op_norm _ _ + ... = β€–(lm x : π•œ)β€– * (β€–frβ€– * β€–xβ€–) : by rw [norm_smul, norm_conj, mul_left_comm] end /-- Extend `fr : F β†’L[ℝ] ℝ` to `F β†’L[π•œ] π•œ`. -/ -noncomputable def continuous_linear_map.extend_to_π•œ' [normed_space ℝ F] [is_scalar_tower ℝ π•œ F] - (fr : F β†’L[ℝ] ℝ) : - F β†’L[π•œ] π•œ := -linear_map.mk_continuous _ (β€–frβ€–) (norm_bound _) +noncomputable def extend_to_π•œ' (fr : F β†’L[ℝ] ℝ) : F β†’L[π•œ] π•œ := +linear_map.mk_continuous _ (β€–frβ€–) fr.norm_extend_to_π•œ'_bound -lemma continuous_linear_map.extend_to_π•œ'_apply [normed_space ℝ F] [is_scalar_tower ℝ π•œ F] - (fr : F β†’L[ℝ] ℝ) (x : F) : +lemma extend_to_π•œ'_apply (fr : F β†’L[ℝ] ℝ) (x : F) : fr.extend_to_π•œ' x = (fr x : π•œ) - (I : π•œ) * fr ((I : π•œ) β€’ x) := rfl +@[simp] lemma norm_extend_to_π•œ' (fr : F β†’L[ℝ] ℝ) : β€–(fr.extend_to_π•œ' : F β†’L[π•œ] π•œ)β€– = β€–frβ€– := +le_antisymm (linear_map.mk_continuous_norm_le _ (norm_nonneg _) _) $ + op_norm_le_bound _ (norm_nonneg _) $ Ξ» x, + calc β€–fr xβ€– = β€–re (fr.extend_to_π•œ' x : π•œ)β€– : congr_arg norm (fr.extend_to_π•œ'_apply_re x).symm + ... ≀ β€–(fr.extend_to_π•œ' x : π•œ)β€– : (abs_re_le_abs _).trans_eq (norm_eq_abs _).symm + ... ≀ β€–(fr.extend_to_π•œ' : F β†’L[π•œ] π•œ)β€– * β€–xβ€– : le_op_norm _ _ + +end continuous_linear_map + /-- Extend `fr : restrict_scalars ℝ π•œ F β†’β‚—[ℝ] ℝ` to `F β†’β‚—[π•œ] π•œ`. -/ noncomputable def linear_map.extend_to_π•œ (fr : (restrict_scalars ℝ π•œ F) β†’β‚—[ℝ] ℝ) : F β†’β‚—[π•œ] π•œ := fr.extend_to_π•œ' @@ -142,3 +141,7 @@ fr.extend_to_π•œ' lemma continuous_linear_map.extend_to_π•œ_apply (fr : (restrict_scalars ℝ π•œ F) β†’L[ℝ] ℝ) (x : F) : fr.extend_to_π•œ x = (fr x : π•œ) - (I : π•œ) * fr ((I : π•œ) β€’ x : _) := rfl + +@[simp] lemma continuous_linear_map.norm_extend_to_π•œ (fr : (restrict_scalars ℝ π•œ F) β†’L[ℝ] ℝ) : + β€–fr.extend_to_π•œβ€– = β€–frβ€– := +fr.norm_extend_to_π•œ' diff --git a/src/analysis/normed_space/hahn_banach/extension.lean b/src/analysis/normed_space/hahn_banach/extension.lean index 74898d0c531ca..80ab1610e970d 100644 --- a/src/analysis/normed_space/hahn_banach/extension.lean +++ b/src/analysis/normed_space/hahn_banach/extension.lean @@ -92,7 +92,7 @@ begin -- And we derive the equality of the norms by bounding on both sides. refine ⟨h, le_antisymm _ _⟩, { calc β€–g.extend_to_π•œβ€– - ≀ β€–gβ€– : g.extend_to_π•œ.op_norm_le_bound g.op_norm_nonneg (norm_bound _) + = β€–gβ€– : g.norm_extend_to_π•œ ... = β€–frβ€– : hnormeq ... ≀ β€–re_clmβ€– * β€–fβ€– : continuous_linear_map.op_norm_comp_le _ _ ... = β€–fβ€– : by rw [re_clm_norm, one_mul] },