Skip to content

Commit 0f320b0

Browse files
committed
feat(Topology/MetricSpace): the L^p direct sum of metric spaces (#40212)
Endow the direct sum `ι →₀ X` of `ι`-many copies of a metric space `X` with the L^p metric for any `1 ≤ p < ∞`. `p = ∞` is theoretically possible too but currently annoying due to defects in our tactics/`WithTop` API. I am leaving it as future work. [Zulip](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/What.20topology.20on.20Finsupp.3F/with/600119738)
1 parent 3b9fc57 commit 0f320b0

9 files changed

Lines changed: 125 additions & 14 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,7 @@ public import Mathlib.Analysis.Normed.Group.Tannery
21802180
public import Mathlib.Analysis.Normed.Group.Ultra
21812181
public import Mathlib.Analysis.Normed.Group.Uniform
21822182
public import Mathlib.Analysis.Normed.Group.ZeroAtInfty
2183+
public import Mathlib.Analysis.Normed.Lp.Finsupp
21832184
public import Mathlib.Analysis.Normed.Lp.LpEquiv
21842185
public import Mathlib.Analysis.Normed.Lp.Matrix
21852186
public import Mathlib.Analysis.Normed.Lp.MeasurableSpace

Mathlib/Algebra/MvPolynomial/SchwartzZippel.lean

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ lemma schwartz_zippel_totalDegree {n} {p : MvPolynomial (Fin n) R} (hp : p ≠ 0
197197
_ = p.totalDegree / #S := by
198198
obtain rfl | hs := S.eq_empty_or_nonempty
199199
· simp
200-
simp only [← _root_.bot_eq_zero, sup_bot]
201200
simp_rw [totalDegree, Nat.cast_finsetSup]
202201
rw [sup_div₀ (by positivity)]
203202
simp [← sum_div, Finsupp.sum_fintype]

Mathlib/Algebra/Order/Monoid/Canonical/Basic.lean

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@ public import Mathlib.Algebra.Order.Sub.Unbundled.Basic
1515

1616
public section
1717

18-
namespace Finset
19-
variable {ι α : Type*} [AddCommMonoid α] [LinearOrder α] [OrderBot α] [CanonicallyOrderedAdd α]
20-
{s : Finset ι} {f : ι → α}
21-
22-
@[simp] lemma sup_eq_zero : s.sup f = 0 ↔ ∀ i ∈ s, f i = 0 := by simp [← bot_eq_zero']
23-
@[simp] lemma sup'_eq_zero (hs) : s.sup' hs f = 0 ↔ ∀ i ∈ s, f i = 0 := by simp [sup'_eq_sup]
24-
25-
end Finset
26-
2718
namespace Set
2819
variable {α : Type*} [AddCommMonoid α] [PartialOrder α] [CanonicallyOrderedAdd α]
2920
[Sub α] [OrderedSub α] {β : Type*} {f : α → β} {k : α}

Mathlib/Analysis/InnerProductSpace/PiL2.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@ open Matrix LinearMap EuclideanSpace in
13211321
theorem InnerProductSpace.symm_toEuclideanLin_rankOne {𝕜 m n : Type*} [RCLike 𝕜] [Fintype m]
13221322
[Fintype n] [DecidableEq n] (x : EuclideanSpace 𝕜 m) (y : EuclideanSpace 𝕜 n) :
13231323
toEuclideanLin.symm (rankOne 𝕜 x y) = .vecMulVec x (star y) := by
1324-
simp [toLpLin, toMatrix', ← ext_iff, vecMulVec_apply, inner_single_right, mul_comm]
1324+
simp [toLpLin, toMatrix', ← Matrix.ext_iff, vecMulVec_apply, inner_single_right, mul_comm]
13251325

13261326
namespace FiniteDimensional
13271327
variable [Unique ι] (h : Module.finrank 𝕜 E = 1) {v : E} (hv : ‖v‖ = 1)
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/-
2+
Copyright (c) 2026 Yaël Dillies. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Yaël Dillies
5+
-/
6+
module
7+
8+
public import Mathlib.Algebra.BigOperators.Finsupp.Basic
9+
public import Mathlib.Analysis.Normed.Lp.WithLp
10+
public import Mathlib.Analysis.SpecialFunctions.Pow.NNReal
11+
public import Mathlib.Topology.MetricSpace.Basic
12+
13+
import Mathlib.Algebra.Order.BigOperators.Group.Finset
14+
import Mathlib.Analysis.MeanInequalities
15+
import Mathlib.Data.ENNReal.BigOperators
16+
import Mathlib.Tactic.Positivity.Finset
17+
18+
/-!
19+
# Direct sum of metric spaces
20+
21+
This files endows the direct sum `ι →₀ X` of `ι`-many copies of a metric space `X` with the
22+
L^p metric.
23+
24+
## TODO
25+
26+
Allow the L^∞ metric too. Currently, there is no easy way to perform the proofs:
27+
`match` on `ℝ≥0∞` exposes the underlying `Option` and `induction p using ENNReal.recTopCoe` in the
28+
`EMetricSpace` instance chokes on the `PseudoEMetricSpace` one.
29+
-/
30+
31+
open scoped ENNReal NNReal
32+
33+
public section
34+
35+
namespace Finsupp
36+
variable {ι X : Type*} [Zero X] {p : ℝ≥0} [Fact (1 ≤ p)]
37+
38+
/-- The L^1 extended metric on `ι`-many copies of a metric space `X` -/
39+
noncomputable instance [PseudoEMetricSpace X] : PseudoEMetricSpace (WithLp p <| ι →₀ X) where
40+
edist f g :=
41+
((f.ofLp.zipWith edist (edist_self _) g.ofLp).sum fun i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ)
42+
edist_self f := by
43+
have : 0 < p := zero_lt_one.trans_le Fact.out
44+
simp [sum, *]
45+
edist_comm f g := by
46+
simp only [sum, zipWith_apply, edist_comm]
47+
congr 2
48+
ext i
49+
simp [edist_comm]
50+
edist_triangle f g h := by
51+
classical
52+
have : 0 < p := zero_lt_one.trans_le Fact.out
53+
let s := f.ofLp.support ∪ g.ofLp.support ∪ h.ofLp.support
54+
rw [sum_of_support_subset (s := s) _ (by grind [support_zipWith]) _ (by simp [*]),
55+
sum_of_support_subset (s := s) _ (by grind [support_zipWith]) _ (by simp [*]),
56+
sum_of_support_subset (s := s) _ (by grind [support_zipWith]) _ (by simp [*])]
57+
simp only [zipWith_apply, ← one_div]
58+
grw [← ENNReal.Lp_add_le _ _ _ (mod_cast Fact.out)]
59+
gcongr
60+
exact edist_triangle ..
61+
62+
lemma edist_def [PseudoEMetricSpace X] {p : ℝ≥0} [Fact (1 ≤ p)]
63+
(f g : WithLp p <| ι →₀ X) :
64+
edist f g =
65+
((f.ofLp.zipWith edist (edist_self _) g.ofLp).sum fun _i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ) := rfl
66+
67+
/-- The L^1 extended metric on `ι`-many copies of a metric space `X` -/
68+
noncomputable instance [EMetricSpace X] : EMetricSpace (WithLp p <| ι →₀ X) where
69+
eq_of_edist_eq_zero {f g} hfg := by simp_all [edist_def, sum, WithLp.ext_iff, DFunLike.ext_iff]
70+
71+
/-- The L^1 metric on `ι`-many copies of a metric space `X` -/
72+
noncomputable instance [PseudoMetricSpace X] : PseudoMetricSpace (WithLp p <| ι →₀ X) :=
73+
PseudoEMetricSpace.toPseudoMetricSpaceOfDist
74+
(fun f g ↦ ((f.ofLp.zipWith dist (dist_self _) g.ofLp).sum fun i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ))
75+
(fun f g ↦ by dsimp [sum]; positivity) fun f g ↦ by
76+
simp only [edist_def, sum, zipWith_apply, ← coe_nnreal_ennreal_nndist, NNReal.zero_le_coe,
77+
← ENNReal.coe_rpow_of_nonneg, ← ENNReal.ofNNReal_finsetSum, inv_nonneg, ← coe_nndist,
78+
← NNReal.coe_rpow, ← NNReal.coe_sum, ENNReal.ofReal_coe_nnreal, ENNReal.coe_inj]
79+
congr! 2
80+
ext i
81+
simp [← coe_nndist, ← coe_nnreal_ennreal_nndist]
82+
83+
lemma dist_def [PseudoMetricSpace X] (f g : WithLp p <| ι →₀ X) :
84+
dist f g =
85+
((f.ofLp.zipWith dist (dist_self _) g.ofLp).sum fun _i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ) := rfl
86+
87+
lemma nndist_def [PseudoMetricSpace X] (f g : WithLp p <| ι →₀ X) :
88+
nndist f g =
89+
((f.ofLp.zipWith nndist (nndist_self _) g.ofLp).sum fun _i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ) := by
90+
ext
91+
simp only [coe_nndist, dist_def, sum, zipWith_apply, NNReal.coe_sum, NNReal.coe_rpow]
92+
congr 2
93+
ext i
94+
simp [← coe_nndist]
95+
96+
/-- The L^1 metric on `ι`-many copies of a metric space `X` -/
97+
noncomputable instance [MetricSpace X] : MetricSpace (WithLp p <| ι →₀ X) :=
98+
EMetricSpace.toMetricSpaceOfDist
99+
(fun f g ↦ ((f.ofLp.zipWith dist (dist_self _) g.ofLp).sum fun i r ↦ r ^ (p : ℝ)) ^ (p⁻¹ : ℝ))
100+
(fun f g ↦ by dsimp [sum]; positivity) fun f g ↦ by rw [edist_dist, dist_def]
101+
102+
end Finsupp

Mathlib/Analysis/Normed/Lp/WithLp.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ variable {K V}
101101
lemma ofLp_toLp (x : V) : ofLp (toLp p x) = x := rfl
102102
@[simp] lemma toLp_ofLp (x : WithLp p V) : toLp p (ofLp x) = x := rfl
103103

104+
lemma ext_iff {x y : WithLp p V} : x = y ↔ x.ofLp = y.ofLp :=
105+
(WithLp.equiv p V).injective.eq_iff.symm
106+
104107
lemma ofLp_surjective : Function.Surjective (@ofLp p V) :=
105108
Function.RightInverse.surjective <| ofLp_toLp _
106109

Mathlib/Data/ENNReal/Basic.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ instance : Inhabited ℝ≥0∞ := ⟨0⟩
191191
def recTopCoe {C : ℝ≥0∞ → Sort*} (top : C ∞) (coe : ∀ x : ℝ≥0, C x) (x : ℝ≥0∞) : C x :=
192192
WithTop.recTopCoe top coe x
193193

194+
@[simp] lemma recTopCoe_top {C : ℝ≥0∞ → Sort*} (top : C ∞) (coe : ∀ x : ℝ≥0, C x) :
195+
recTopCoe top coe ∞ = top := rfl
196+
197+
@[simp] lemma recTopCoe_ofNNReal {C : ℝ≥0∞ → Sort*} (top : C ∞) (coe : ∀ x : ℝ≥0, C x) (x : ℝ≥0) :
198+
recTopCoe top coe x = coe x := rfl
199+
194200
instance canLift : CanLift ℝ≥0∞ ℝ≥0 ofNNReal (· ≠ ∞) := WithTop.canLift
195201

196202
@[simp] theorem none_eq_top : (none : ℝ≥0∞) = ∞ := rfl

Mathlib/Data/Finset/Lattice/Fold.lean

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ theorem sup_mem (s : Set α) (w₁ : ⊥ ∈ s) (w₂ : ∀ᵉ (x ∈ s) (y ∈
260260
protected theorem sup_eq_bot_iff (f : β → α) (S : Finset β) : S.sup f = ⊥ ↔ ∀ s ∈ S, f s = ⊥ := by
261261
classical induction S using Finset.induction <;> simp [*]
262262

263+
@[to_additive (attr := simp)]
264+
lemma sup_eq_one [One α] [IsBotOneClass α] : s.sup f = 1 ↔ ∀ i ∈ s, f i = 1 := by
265+
simp [← bot_eq_one]
266+
263267
@[to_dual (attr := simp)]
264268
lemma sup_disjSum (s : Finset β) (t : Finset γ) (f : β ⊕ γ → α) :
265269
(s.disjSum t).sup f = (s.sup fun x ↦ f (.inl x)) ⊔ (t.sup fun x ↦ f (.inr x)) :=
@@ -663,14 +667,18 @@ end Sup'
663667

664668
section Sup
665669

666-
variable [SemilatticeSup α] [OrderBot α]
670+
variable [SemilatticeSup α] [OrderBot α] {s : Finset β} {f : β → α}
667671

668672
@[to_dual]
669-
theorem sup'_eq_sup {s : Finset β} (H : s.Nonempty) (f : β → α) : s.sup' H f = s.sup f :=
673+
theorem sup'_eq_sup (H : s.Nonempty) (f : β → α) : s.sup' H f = s.sup f :=
670674
le_antisymm (sup'_le H f fun _ => le_sup) (Finset.sup_le fun _ => le_sup' f)
671675

676+
@[to_additive (attr := simp)]
677+
lemma sup'_eq_one [One α] [IsBotOneClass α] (hs) : s.sup' hs f = 1 ↔ ∀ i ∈ s, f i = 1 := by
678+
simp [sup'_eq_sup]
679+
672680
@[to_dual]
673-
theorem coe_sup_of_nonempty {s : Finset β} (h : s.Nonempty) (f : β → α) :
681+
theorem coe_sup_of_nonempty (h : s.Nonempty) (f : β → α) :
674682
(↑(s.sup f) : WithBot α) = s.sup ((↑) ∘ f) := by simp only [← sup'_eq_sup h, coe_sup' h]
675683

676684
end Sup

Mathlib/Data/NNReal/Defs.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ theorem _root_.Real.le_coe_toNNReal (r : ℝ) : r ≤ Real.toNNReal r :=
165165
le_max_left r 0
166166

167167
@[bound] theorem coe_nonneg (r : ℝ≥0) : (0 : ℝ) ≤ r := r.2
168+
@[simp] lemma not_toReal_neg {r : ℝ≥0} : ¬ r.toReal < 0 := r.coe_nonneg.not_gt
168169

169170
@[simp, norm_cast] theorem coe_mk (a : ℝ) (ha) : toReal (.mk a ha) = a := rfl
170171

0 commit comments

Comments
 (0)