-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: port Analysis.InnerProductSpace.OfNorm (#5885)
- Loading branch information
1 parent
3bf1e11
commit a2fecf3
Showing
2 changed files
with
357 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,356 @@ | ||
/- | ||
Copyright (c) 2020 Heather Macbeth. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Heather Macbeth | ||
! This file was ported from Lean 3 source module analysis.inner_product_space.of_norm | ||
! leanprover-community/mathlib commit baa88307f3e699fa7054ef04ec79fa4f056169cb | ||
! Please do not edit these lines, except to modify the commit id | ||
! if you have ported upstream changes. | ||
-/ | ||
import Mathlib.Topology.Algebra.Algebra | ||
import Mathlib.Analysis.InnerProductSpace.Basic | ||
|
||
/-! | ||
# Inner product space derived from a norm | ||
This file defines an `InnerProductSpace` instance from a norm that respects the | ||
parallellogram identity. The parallelogram identity is a way to express the inner product of `x` and | ||
`y` in terms of the norms of `x`, `y`, `x + y`, `x - y`. | ||
## Main results | ||
- `InnerProductSpace.ofNorm`: a normed space whose norm respects the parallellogram identity, | ||
can be seen as an inner product space. | ||
## Implementation notes | ||
We define `inner_` | ||
$$\langle x, y \rangle := \frac{1}{4} (βx + yβ^2 - βx - yβ^2 + i βix + yβ ^ 2 - i βix - yβ^2)$$ | ||
and use the parallelogram identity | ||
$$βx + yβ^2 + βx - yβ^2 = 2 (βxβ^2 + βyβ^2)$$ | ||
to prove it is an inner product, i.e., that it is conjugate-symmetric (`Inner_.conj_symm`) and | ||
linear in the first argument. `add_left` is proved by judicious application of the parallelogram | ||
identity followed by tedious arithmetic. `smul_left` is proved step by step, first noting that | ||
$\langle Ξ» x, y \rangle = Ξ» \langle x, y \rangle$ for $Ξ» β β$, $Ξ» = -1$, hence $Ξ» β β€$ and $Ξ» β β$ | ||
by arithmetic. Then by continuity and the fact that β is dense in β, the same is true for β. | ||
The case of β then follows by applying the result for β and more arithmetic. | ||
## TODO | ||
Move upstream to `Analysis.InnerProductSpace.Basic`. | ||
## References | ||
- [Jordan, P. and von Neumann, J., *On inner products in linear, metric spaces*][Jordan1935] | ||
- https://math.stackexchange.com/questions/21792/norms-induced-by-inner-products-and-the-parallelogram-law | ||
- https://math.dartmouth.edu/archive/m113w10/public_html/jordan-vneumann-thm.pdf | ||
## Tags | ||
inner product space, Hilbert space, norm | ||
-/ | ||
|
||
|
||
open IsROrC | ||
|
||
open scoped ComplexConjugate | ||
|
||
variable {π : Type _} [IsROrC π] (E : Type _) [NormedAddCommGroup E] | ||
|
||
/-- Predicate for the parallelogram identity to hold in a normed group. This is a scalar-less | ||
version of `InnerProductSpace`. If you have an `InnerProductSpaceable` assumption, you can | ||
locally upgrade that to `InnerProductSpace π E` using `casesI nonempty_innerProductSpace π E`. | ||
-/ | ||
class InnerProductSpaceable : Prop where | ||
parallelogram_identity : | ||
β x y : E, βx + yβ * βx + yβ + βx - yβ * βx - yβ = 2 * (βxβ * βxβ + βyβ * βyβ) | ||
#align inner_product_spaceable InnerProductSpaceable | ||
|
||
variable (π) {E} | ||
|
||
theorem InnerProductSpace.toInnerProductSpaceable [InnerProductSpace π E] : | ||
InnerProductSpaceable E := | ||
β¨parallelogram_law_with_norm πβ© | ||
#align inner_product_space.to_inner_product_spaceable InnerProductSpace.toInnerProductSpaceable | ||
|
||
-- See note [lower instance priority] | ||
instance (priority := 100) InnerProductSpace.toInnerProductSpaceable_ofReal | ||
[InnerProductSpace β E] : InnerProductSpaceable E := | ||
β¨parallelogram_law_with_norm ββ© | ||
#align inner_product_space.to_inner_product_spaceable_of_real InnerProductSpace.toInnerProductSpaceable_ofReal | ||
|
||
variable [NormedSpace π E] | ||
|
||
local notation "π" => algebraMap β π | ||
|
||
/-- Auxiliary definition of the inner product derived from the norm. -/ | ||
private noncomputable def inner_ (x y : E) : π := | ||
4β»ΒΉ * (π βx + yβ * π βx + yβ - π βx - yβ * π βx - yβ + | ||
(I : π) * π β(I : π) β’ x + yβ * π β(I : π) β’ x + yβ - | ||
(I : π) * π β(I : π) β’ x - yβ * π β(I : π) β’ x - yβ) | ||
|
||
namespace InnerProductSpaceable | ||
|
||
variable {π} (E) | ||
|
||
-- Porting note: prime added to avoid clashing with public `innerProp` | ||
/-- Auxiliary definition for the `add_left` property. -/ | ||
private def innerProp' (r : π) : Prop := | ||
β x y : E, inner_ π (r β’ x) y = conj r * inner_ π x y | ||
|
||
variable {E} | ||
|
||
theorem innerProp_neg_one : innerProp' E ((-1 : β€) : π) := by | ||
intro x y | ||
simp only [inner_, neg_mul_eq_neg_mul, one_mul, Int.cast_one, one_smul, RingHom.map_one, map_neg, | ||
Int.cast_neg, neg_smul, neg_one_mul] | ||
rw [neg_mul_comm] | ||
congr 1 | ||
have hβ : β-x - yβ = βx + yβ := by rw [β neg_add', norm_neg] | ||
have hβ : β-x + yβ = βx - yβ := by rw [β neg_sub, norm_neg, sub_eq_neg_add] | ||
have hβ : β(I : π) β’ -x + yβ = β(I : π) β’ x - yβ := by | ||
rw [β neg_sub, norm_neg, sub_eq_neg_add, β smul_neg] | ||
have hβ : β(I : π) β’ -x - yβ = β(I : π) β’ x + yβ := by rw [smul_neg, β neg_add', norm_neg] | ||
rw [hβ, hβ, hβ, hβ] | ||
ring | ||
#align inner_product_spaceable.inner_prop_neg_one InnerProductSpaceable.innerProp_neg_one | ||
|
||
theorem _root_.Continuous.inner_ {f g : β β E} (hf : Continuous f) (hg : Continuous g) : | ||
Continuous fun x => inner_ π (f x) (g x) := by | ||
unfold inner_ | ||
have := Continuous.const_smul (M := π) hf I | ||
continuity | ||
#align inner_product_spaceable.continuous.inner_ Continuous.inner_ | ||
|
||
theorem Inner_.norm_sq (x : E) : βxβ ^ 2 = re (inner_ π x x) := by | ||
simp only [inner_] | ||
have hβ : IsROrC.normSq (4 : π) = 16 := by | ||
have : ((4 : β) : π) = (4 : π) := by norm_cast | ||
rw [β this, normSq_eq_def', IsROrC.norm_of_nonneg (by norm_num : (0 : β) β€ 4)] | ||
norm_num | ||
have hβ : βx + xβ = 2 * βxβ := by rw [β two_smul π, norm_smul, IsROrC.norm_two] | ||
simp only [hβ, hβ, algebraMap_eq_ofReal, sub_self, norm_zero, mul_re, inv_re, ofNat_re, map_sub, | ||
map_add, ofReal_re, ofNat_im, ofReal_im, mul_im, I_re, inv_im] | ||
ring | ||
#align inner_product_spaceable.inner_.norm_sq InnerProductSpaceable.Inner_.norm_sq | ||
|
||
theorem Inner_.conj_symm (x y : E) : conj (inner_ π y x) = inner_ π x y := by | ||
simp only [inner_] | ||
have h4 : conj (4β»ΒΉ : π) = 4β»ΒΉ := by norm_num | ||
rw [map_mul, h4] | ||
congr 1 | ||
simp only [map_sub, map_add, algebraMap_eq_ofReal, β ofReal_mul, conj_ofReal, map_mul, conj_I] | ||
rw [add_comm y x, norm_sub_rev] | ||
by_cases hI : (I : π) = 0 | ||
Β· simp only [hI, neg_zero, MulZeroClass.zero_mul] | ||
-- Porting note: this replaces `norm_I_of_ne_zero` which does not exist in Lean 4 | ||
have : β(I : π)β = 1 := by | ||
rw [β mul_self_inj_of_nonneg (norm_nonneg I) zero_le_one, one_mul, β norm_mul, | ||
I_mul_I_of_nonzero hI, norm_neg, norm_one] | ||
have hβ : β(I : π) β’ y - xβ = β(I : π) β’ x + yβ := by | ||
trans β(I : π) β’ ((I : π) β’ y - x)β | ||
Β· rw [norm_smul, this, one_mul] | ||
Β· rw [smul_sub, smul_smul, I_mul_I_of_nonzero hI, neg_one_smul, β neg_add', add_comm, norm_neg] | ||
have hβ : β(I : π) β’ y + xβ = β(I : π) β’ x - yβ := by | ||
trans β(I : π) β’ ((I : π) β’ y + x)β | ||
Β· rw [norm_smul, this, one_mul] | ||
Β· rw [smul_add, smul_smul, I_mul_I_of_nonzero hI, neg_one_smul, β neg_add_eq_sub] | ||
rw [hβ, hβ, β sub_add_eq_add_sub] | ||
simp only [neg_mul, sub_eq_add_neg, neg_neg] | ||
#align inner_product_spaceable.inner_.conj_symm InnerProductSpaceable.Inner_.conj_symm | ||
|
||
variable [InnerProductSpaceable E] | ||
|
||
private theorem add_left_aux1 (x y z : E) : βx + y + zβ * βx + y + zβ = | ||
(β2 β’ x + yβ * β2 β’ x + yβ + β2 β’ z + yβ * β2 β’ z + yβ) / 2 - βx - zβ * βx - zβ := by | ||
rw [eq_sub_iff_add_eq, eq_div_iff (two_ne_zero' β), mul_comm _ (2 : β), eq_comm] | ||
convert parallelogram_identity (x + y + z) (x - z) using 4 <;> Β· rw [two_smul]; abel | ||
|
||
private theorem add_left_aux2 (x y z : E) : βx + y - zβ * βx + y - zβ = | ||
(β2 β’ x + yβ * β2 β’ x + yβ + βy - 2 β’ zβ * βy - 2 β’ zβ) / 2 - βx + zβ * βx + zβ := by | ||
rw [eq_sub_iff_add_eq, eq_div_iff (two_ne_zero' β), mul_comm _ (2 : β), eq_comm] | ||
have hβ := parallelogram_identity (x + y - z) (x + z) | ||
convert hβ using 4 <;> Β· rw [two_smul]; abel | ||
|
||
private theorem add_left_aux2' (x y z : E) : | ||
βx + y + zβ * βx + y + zβ - βx + y - zβ * βx + y - zβ = | ||
βx + zβ * βx + zβ - βx - zβ * βx - zβ + | ||
(β2 β’ z + yβ * β2 β’ z + yβ - βy - 2 β’ zβ * βy - 2 β’ zβ) / 2 := by | ||
rw [add_left_aux1, add_left_aux2]; ring | ||
|
||
private theorem add_left_aux3 (y z : E) : | ||
β2 β’ z + yβ * β2 β’ z + yβ = 2 * (βy + zβ * βy + zβ + βzβ * βzβ) - βyβ * βyβ := by | ||
apply eq_sub_of_add_eq | ||
convert parallelogram_identity (y + z) z using 4 <;> (try rw [two_smul]) <;> abel | ||
|
||
private theorem add_left_aux4 (y z : E) : | ||
βy - 2 β’ zβ * βy - 2 β’ zβ = 2 * (βy - zβ * βy - zβ + βzβ * βzβ) - βyβ * βyβ := by | ||
apply eq_sub_of_add_eq' | ||
have hβ := parallelogram_identity (y - z) z | ||
convert hβ using 4 <;> (try rw [two_smul]) <;> abel | ||
|
||
private theorem add_left_aux4' (y z : E) : | ||
(β2 β’ z + yβ * β2 β’ z + yβ - βy - 2 β’ zβ * βy - 2 β’ zβ) / 2 = | ||
βy + zβ * βy + zβ - βy - zβ * βy - zβ := by | ||
rw [add_left_aux3, add_left_aux4]; ring | ||
|
||
private theorem add_left_aux5 (x y z : E) : | ||
β(I : π) β’ (x + y) + zβ * β(I : π) β’ (x + y) + zβ = | ||
(β(I : π) β’ (2 β’ x + y)β * β(I : π) β’ (2 β’ x + y)β + | ||
β(I : π) β’ y + 2 β’ zβ * β(I : π) β’ y + 2 β’ zβ) / 2 - | ||
β(I : π) β’ x - zβ * β(I : π) β’ x - zβ := by | ||
rw [eq_sub_iff_add_eq, eq_div_iff (two_ne_zero' β), mul_comm _ (2 : β), eq_comm] | ||
have hβ := parallelogram_identity ((I : π) β’ (x + y) + z) ((I : π) β’ x - z) | ||
convert hβ using 4 <;> Β· try simp only [two_smul, smul_add]; abel | ||
|
||
private theorem add_left_aux6 (x y z : E) : | ||
β(I : π) β’ (x + y) - zβ * β(I : π) β’ (x + y) - zβ = | ||
(β(I : π) β’ (2 β’ x + y)β * β(I : π) β’ (2 β’ x + y)β + | ||
β(I : π) β’ y - 2 β’ zβ * β(I : π) β’ y - 2 β’ zβ) / 2 - | ||
β(I : π) β’ x + zβ * β(I : π) β’ x + zβ := by | ||
rw [eq_sub_iff_add_eq, eq_div_iff (two_ne_zero' β), mul_comm _ (2 : β), eq_comm] | ||
have hβ := parallelogram_identity ((I : π) β’ (x + y) - z) ((I : π) β’ x + z) | ||
convert hβ using 4 <;> Β· try simp only [two_smul, smul_add]; abel | ||
|
||
private theorem add_left_aux7 (y z : E) : | ||
β(I : π) β’ y + 2 β’ zβ * β(I : π) β’ y + 2 β’ zβ = | ||
2 * (β(I : π) β’ y + zβ * β(I : π) β’ y + zβ + βzβ * βzβ) - β(I : π) β’ yβ * β(I : π) β’ yβ := by | ||
apply eq_sub_of_add_eq | ||
have hβ := parallelogram_identity ((I : π) β’ y + z) z | ||
convert hβ using 4 <;> Β· try simp only [two_smul, smul_add]; abel | ||
|
||
private theorem add_left_aux8 (y z : E) : | ||
β(I : π) β’ y - 2 β’ zβ * β(I : π) β’ y - 2 β’ zβ = | ||
2 * (β(I : π) β’ y - zβ * β(I : π) β’ y - zβ + βzβ * βzβ) - β(I : π) β’ yβ * β(I : π) β’ yβ := by | ||
apply eq_sub_of_add_eq' | ||
have hβ := parallelogram_identity ((I : π) β’ y - z) z | ||
convert hβ using 4 <;> Β· try simp only [two_smul, smul_add]; abel | ||
|
||
theorem add_left (x y z : E) : inner_ π (x + y) z = inner_ π x z + inner_ π y z := by | ||
simp only [inner_, β mul_add] | ||
congr | ||
simp only [mul_assoc, β map_mul, add_sub_assoc, β mul_sub, β map_sub] | ||
rw [add_add_add_comm] | ||
simp only [β map_add, β mul_add] | ||
congr | ||
Β· rw [β add_sub_assoc, add_left_aux2', add_left_aux4'] | ||
Β· rw [add_left_aux5, add_left_aux6, add_left_aux7, add_left_aux8] | ||
simp only [map_sub, map_mul, map_add, div_eq_mul_inv] | ||
ring | ||
#align inner_product_spaceable.add_left InnerProductSpaceable.add_left | ||
|
||
theorem nat (n : β) (x y : E) : inner_ π ((n : π) β’ x) y = (n : π) * inner_ π x y := by | ||
induction' n with n ih | ||
Β· simp only [inner_, Nat.zero_eq, zero_sub, Nat.cast_zero, MulZeroClass.zero_mul, | ||
eq_self_iff_true, zero_smul, zero_add, MulZeroClass.mul_zero, sub_self, norm_neg, smul_zero] | ||
Β· simp only [Nat.cast_succ, add_smul, one_smul] | ||
rw [add_left, ih, add_mul, one_mul] | ||
#align inner_product_spaceable.nat InnerProductSpaceable.nat | ||
|
||
private theorem nat_prop (r : β) : innerProp' E (r : π) := fun x y => by | ||
simp only [map_natCast]; exact nat r x y | ||
|
||
private theorem int_prop (n : β€) : innerProp' E (n : π) := by | ||
intro x y | ||
rw [β n.sign_mul_natAbs] | ||
simp only [Int.cast_ofNat, map_natCast, map_intCast, Int.cast_mul, map_mul, mul_smul] | ||
obtain hn | rfl | hn := lt_trichotomy n 0 | ||
Β· rw [Int.sign_eq_neg_one_of_neg hn, innerProp_neg_one ((n.natAbs : π) β’ x), nat] | ||
simp only [map_neg, neg_mul, one_mul, mul_eq_mul_left_iff, true_or_iff, Int.natAbs_eq_zero, | ||
eq_self_iff_true, Int.cast_one, map_one, neg_inj, Nat.cast_eq_zero, Int.cast_neg] | ||
Β· simp only [inner_, Int.cast_zero, zero_sub, Nat.cast_zero, MulZeroClass.zero_mul, | ||
eq_self_iff_true, Int.sign_zero, zero_smul, zero_add, MulZeroClass.mul_zero, smul_zero, | ||
sub_self, norm_neg, Int.natAbs_zero] | ||
Β· rw [Int.sign_eq_one_of_pos hn] | ||
simp only [one_mul, mul_eq_mul_left_iff, true_or_iff, Int.natAbs_eq_zero, eq_self_iff_true, | ||
Int.cast_one, one_smul, Nat.cast_eq_zero, nat] | ||
|
||
private theorem rat_prop (r : β) : innerProp' E (r : π) := by | ||
intro x y | ||
have : (r.den : π) β 0 := by | ||
haveI : CharZero π := IsROrC.charZero_isROrC | ||
exact_mod_cast r.pos.ne' | ||
rw [β r.num_div_den, β mul_right_inj' this, β nat r.den _ y, smul_smul, Rat.cast_div] | ||
simp only [map_natCast, Rat.cast_coe_nat, map_intCast, Rat.cast_coe_int, map_divβ] | ||
rw [β mul_assoc, mul_div_cancel' _ this, int_prop _ x, map_intCast] | ||
|
||
private theorem real_prop (r : β) : innerProp' E (r : π) := by | ||
intro x y | ||
revert r | ||
rw [β Function.funext_iff] | ||
refine' Rat.denseEmbedding_coe_real.dense.equalizer _ _ (funext fun X => _) | ||
Β· exact (continuous_ofReal.smul continuous_const).inner_ continuous_const | ||
Β· exact (continuous_conj.comp continuous_ofReal).mul continuous_const | ||
Β· simp only [Function.comp_apply, IsROrC.ofReal_ratCast, rat_prop _ _] | ||
|
||
private theorem I_prop : innerProp' E (I : π) := by | ||
by_cases hI : (I : π) = 0 | ||
Β· rw [hI, β Nat.cast_zero]; exact nat_prop _ | ||
intro x y | ||
have hI' : (-I : π) * I = 1 := by rw [β inv_I, inv_mul_cancel hI] | ||
rw [conj_I, inner_, inner_, mul_left_comm] | ||
congr 1 | ||
rw [smul_smul, I_mul_I_of_nonzero hI, neg_one_smul] | ||
rw [mul_sub, mul_add, mul_sub, mul_assoc I (π βI β’ x - yβ), β mul_assoc (-I) I, hI', one_mul, | ||
mul_assoc I (π βI β’ x + yβ), β mul_assoc (-I) I, hI', one_mul] | ||
have hβ : β-x - yβ = βx + yβ := by rw [β neg_add', norm_neg] | ||
have hβ : β-x + yβ = βx - yβ := by rw [β neg_sub, norm_neg, sub_eq_neg_add] | ||
rw [hβ, hβ] | ||
simp only [sub_eq_add_neg, mul_assoc] | ||
rw [β neg_mul_eq_neg_mul, β neg_mul_eq_neg_mul] | ||
abel | ||
|
||
theorem innerProp (r : π) : innerProp' E r := by | ||
intro x y | ||
rw [β re_add_im r, add_smul, add_left, real_prop _ x, β smul_smul, real_prop _ _ y, I_prop, | ||
map_add, map_mul, conj_ofReal, conj_ofReal, conj_I] | ||
ring | ||
#align inner_product_spaceable.inner_prop InnerProductSpaceable.innerProp | ||
|
||
end InnerProductSpaceable | ||
|
||
open InnerProductSpaceable | ||
|
||
/-- **FrΓ©chetβvon NeumannβJordan Theorem**. A normed space `E` whose norm satisfies the | ||
parallelogram identity can be given a compatible inner product. -/ | ||
noncomputable def InnerProductSpace.ofNorm | ||
(h : β x y : E, βx + yβ * βx + yβ + βx - yβ * βx - yβ = 2 * (βxβ * βxβ + βyβ * βyβ)) : | ||
InnerProductSpace π E := | ||
haveI : InnerProductSpaceable E := β¨hβ© | ||
{ inner := inner_ π | ||
norm_sq_eq_inner := Inner_.norm_sq | ||
conj_symm := Inner_.conj_symm | ||
add_left := InnerProductSpaceable.add_left | ||
smul_left := fun _ _ _ => innerProp _ _ _ } | ||
#align inner_product_space.of_norm InnerProductSpace.ofNorm | ||
|
||
variable (E) | ||
|
||
variable [InnerProductSpaceable E] | ||
|
||
/-- **FrΓ©chetβvon NeumannβJordan Theorem**. A normed space `E` whose norm satisfies the | ||
parallelogram identity can be given a compatible inner product. Do | ||
`casesI nonempty_innerProductSpace π E` to locally upgrade `InnerProductSpaceable E` to | ||
`InnerProductSpace π E`. -/ | ||
theorem nonempty_innerProductSpace : Nonempty (InnerProductSpace π E) := | ||
β¨{ inner := inner_ π | ||
norm_sq_eq_inner := Inner_.norm_sq | ||
conj_symm := Inner_.conj_symm | ||
add_left := add_left | ||
smul_left := fun _ _ _ => innerProp _ _ _ }β© | ||
#align nonempty_inner_product_space nonempty_innerProductSpace | ||
|
||
variable {π E} | ||
|
||
variable [NormedSpace β E] | ||
|
||
-- TODO: Replace `InnerProductSpace.toUniformConvexSpace` | ||
-- See note [lower instance priority] | ||
instance (priority := 100) InnerProductSpaceable.to_uniformConvexSpace : UniformConvexSpace E := by | ||
cases nonempty_innerProductSpace β E; infer_instance | ||
#align inner_product_spaceable.to_uniform_convex_space InnerProductSpaceable.to_uniformConvexSpace |