Skip to content

Commit ff8b24e

Browse files
feat(EReal): add toENNReal (#18885)
- Add definition of `EReal.toENNReal`. - Add some API lemmas for `toENNReal`. - Add measurability and continuity lemmas for `toENNReal`. Co-authored-by: Lorenzo Luccioli <71074618+LorenzoLuccioli@users.noreply.github.com> Co-authored-by: Remy Degenne <remydegenne@gmail.com>
1 parent 143aee4 commit ff8b24e

File tree

3 files changed

+196
-1
lines changed

3 files changed

+196
-1
lines changed

Mathlib/Data/Real/EReal.lean

Lines changed: 138 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,90 @@ theorem coe_ennreal_mul : ∀ x y : ℝ≥0∞, ((x * y : ℝ≥0∞) : EReal) =
683683
theorem coe_ennreal_nsmul (n : ℕ) (x : ℝ≥0∞) : (↑(n • x) : EReal) = n • (x : EReal) :=
684684
map_nsmul (⟨⟨(↑), coe_ennreal_zero⟩, coe_ennreal_add⟩ : ℝ≥0∞ →+ EReal) _ _
685685

686+
/-! ### toENNReal -/
687+
688+
/-- `x.toENNReal` returns `x` if it is nonnegative, `0` otherwise. -/
689+
noncomputable def toENNReal (x : EReal) : ℝ≥0∞ :=
690+
if x = ⊤ then
691+
else ENNReal.ofReal x.toReal
692+
693+
@[simp] lemma toENNReal_top : (⊤ : EReal).toENNReal = ⊤ := rfl
694+
695+
@[simp]
696+
lemma toENNReal_of_ne_top {x : EReal} (hx : x ≠ ⊤) : x.toENNReal = ENNReal.ofReal x.toReal :=
697+
if_neg hx
698+
699+
@[simp]
700+
lemma toENNReal_eq_top_iff {x : EReal} : x.toENNReal = ⊤ ↔ x = ⊤ := by
701+
by_cases h : x = ⊤
702+
· simp [h]
703+
· simp [h, toENNReal]
704+
705+
lemma toENNReal_ne_top_iff {x : EReal} : x.toENNReal ≠ ⊤ ↔ x ≠ ⊤ := toENNReal_eq_top_iff.not
706+
707+
@[simp]
708+
lemma toENNReal_of_nonpos {x : EReal} (hx : x ≤ 0) : x.toENNReal = 0 := by
709+
rw [toENNReal, if_neg (fun h ↦ ?_)]
710+
· exact ENNReal.ofReal_of_nonpos (toReal_nonpos hx)
711+
· exact zero_ne_top <| top_le_iff.mp <| h ▸ hx
712+
713+
lemma toENNReal_bot : (⊥ : EReal).toENNReal = 0 := toENNReal_of_nonpos bot_le
714+
lemma toENNReal_zero : (0 : EReal).toENNReal = 0 := toENNReal_of_nonpos le_rfl
715+
716+
lemma toENNReal_eq_zero_iff {x : EReal} : x.toENNReal = 0 ↔ x ≤ 0 := by
717+
induction x <;> simp [toENNReal]
718+
719+
lemma toENNReal_ne_zero_iff {x : EReal} : x.toENNReal ≠ 00 < x := by
720+
simp [toENNReal_eq_zero_iff.not]
721+
722+
@[simp]
723+
lemma coe_toENNReal {x : EReal} (hx : 0 ≤ x) : (x.toENNReal : EReal) = x := by
724+
rw [toENNReal]
725+
by_cases h_top : x = ⊤
726+
· rw [if_pos h_top, h_top]
727+
rfl
728+
rw [if_neg h_top]
729+
simp only [coe_ennreal_ofReal, ge_iff_le, hx, toReal_nonneg, max_eq_left]
730+
exact coe_toReal h_top fun _ ↦ by simp_all only [le_bot_iff, zero_ne_bot]
731+
732+
lemma coe_toENNReal_eq_max {x : EReal} : x.toENNReal = max 0 x := by
733+
rcases le_total 0 x with (hx | hx)
734+
· rw [coe_toENNReal hx, max_eq_right hx]
735+
· rw [toENNReal_of_nonpos hx, max_eq_left hx, coe_ennreal_zero]
736+
737+
@[simp]
738+
lemma toENNReal_coe {x : ℝ≥0∞} : (x : EReal).toENNReal = x := by
739+
by_cases h_top : x = ⊤
740+
· rw [h_top, coe_ennreal_top, toENNReal_top]
741+
rwa [toENNReal, if_neg _, toReal_coe_ennreal, ENNReal.ofReal_toReal_eq_iff]
742+
simp [h_top]
743+
744+
@[simp] lemma real_coe_toENNReal (x : ℝ) : (x : EReal).toENNReal = ENNReal.ofReal x := rfl
745+
746+
@[simp]
747+
lemma toReal_toENNReal {x : EReal} (hx : 0 ≤ x) : x.toENNReal.toReal = x.toReal := by
748+
by_cases h : x = ⊤
749+
· simp [h]
750+
· simp [h, toReal_nonneg hx]
751+
752+
lemma toENNReal_eq_toENNReal {x y : EReal} (hx : 0 ≤ x) (hy : 0 ≤ y) :
753+
x.toENNReal = y.toENNReal ↔ x = y := by
754+
induction x <;> induction y <;> simp_all
755+
756+
lemma toENNReal_le_toENNReal {x y : EReal} (h : x ≤ y) : x.toENNReal ≤ y.toENNReal := by
757+
induction x
758+
· simp
759+
· by_cases hy_top : y = ⊤
760+
· simp [hy_top]
761+
simp only [toENNReal, coe_ne_top, ↓reduceIte, toReal_coe, hy_top]
762+
exact ENNReal.ofReal_le_ofReal <| EReal.toReal_le_toReal h (coe_ne_bot _) hy_top
763+
· simp_all
764+
765+
lemma toENNReal_lt_toENNReal {x y : EReal} (hx : 0 ≤ x) (hxy : x < y) :
766+
x.toENNReal < y.toENNReal :=
767+
lt_of_le_of_ne (toENNReal_le_toENNReal hxy.le)
768+
fun h ↦ hxy.ne <| (toENNReal_eq_toENNReal hx (hx.trans_lt hxy).le).mp h
769+
686770
/-! ### nat coercion -/
687771

688772
theorem coe_coe_eq_natCast (n : ℕ) : (n : ℝ) = (n : EReal) := rfl
@@ -826,6 +910,17 @@ theorem toReal_add {x y : EReal} (hx : x ≠ ⊤) (h'x : x ≠ ⊥) (hy : y ≠
826910
lift y to ℝ using ⟨hy, h'y⟩
827911
rfl
828912

913+
lemma toENNReal_add {x y : EReal} (hx : 0 ≤ x) (hy : 0 ≤ y) :
914+
(x + y).toENNReal = x.toENNReal + y.toENNReal := by
915+
induction x <;> induction y <;> try {· simp_all}
916+
norm_cast
917+
simp_rw [real_coe_toENNReal]
918+
simp_all [ENNReal.ofReal_add]
919+
920+
lemma toENNReal_add_le {x y : EReal} : (x + y).toENNReal ≤ x.toENNReal + y.toENNReal := by
921+
induction x <;> induction y <;> try {· simp}
922+
exact ENNReal.ofReal_add_le
923+
829924
theorem addLECancellable_coe (x : ℝ) : AddLECancellable (x : EReal)
830925
| _, ⊤, _ => le_top
831926
| ⊥, _, _ => bot_le
@@ -885,6 +980,16 @@ lemma add_ne_top_iff_ne_top_left {x y : EReal} (hy : y ≠ ⊥) (hy' : y ≠ ⊤
885980
lemma add_ne_top_iff_ne_top_right {x y : EReal} (hx : x ≠ ⊥) (hx' : x ≠ ⊤) :
886981
x + y ≠ ⊤ ↔ y ≠ ⊤ := add_comm x y ▸ add_ne_top_iff_ne_top_left hx hx'
887982

983+
lemma add_ne_top_iff_of_ne_bot {x y : EReal} (hx : x ≠ ⊥) (hy : y ≠ ⊥) :
984+
x + y ≠ ⊤ ↔ x ≠ ⊤ ∧ y ≠ ⊤ := by
985+
refine ⟨?_, fun h ↦ add_ne_top h.1 h.2
986+
induction x <;> simp_all
987+
induction y <;> simp_all
988+
989+
lemma add_ne_top_iff_of_ne_bot_of_ne_top {x y : EReal} (hy : y ≠ ⊥) (hy' : y ≠ ⊤) :
990+
x + y ≠ ⊤ ↔ x ≠ ⊤ := by
991+
induction x <;> simp [add_ne_top_iff_of_ne_bot, hy, hy']
992+
888993
/-- We do not have a notion of `LinearOrderedAddCommMonoidWithBot` but we can at least make
889994
the order dual of the extended reals into a `LinearOrderedAddCommMonoidWithTop`. -/
890995
instance : LinearOrderedAddCommMonoidWithTop ERealᵒᵈ where
@@ -1084,6 +1189,17 @@ theorem toReal_sub {x y : EReal} (hx : x ≠ ⊤) (h'x : x ≠ ⊥) (hy : y ≠
10841189
lift y to ℝ using ⟨hy, h'y⟩
10851190
rfl
10861191

1192+
lemma toENNReal_sub {x y : EReal} (hy : 0 ≤ y) :
1193+
(x - y).toENNReal = x.toENNReal - y.toENNReal := by
1194+
induction x <;> induction y <;> try {· simp_all [zero_tsub, ENNReal.sub_top]}
1195+
rename_i x y
1196+
by_cases hxy : x ≤ y
1197+
· rw [toENNReal_of_nonpos <| sub_nonpos.mpr <| EReal.coe_le_coe_iff.mpr hxy]
1198+
exact (tsub_eq_zero_of_le <| toENNReal_le_toENNReal <| EReal.coe_le_coe_iff.mpr hxy).symm
1199+
· rw [toENNReal_of_ne_top (ne_of_beq_false rfl).symm, ← coe_sub, toReal_coe,
1200+
ofReal_sub x (EReal.coe_nonneg.mp hy)]
1201+
simp
1202+
10871203
lemma add_sub_cancel_right {a : EReal} {b : Real} : a + b - b = a := by
10881204
cases a <;> norm_cast
10891205
exact _root_.add_sub_cancel_right _ _
@@ -1428,6 +1544,27 @@ lemma mul_ne_bot (a b : EReal) :
14281544
set_option push_neg.use_distrib true in push_neg
14291545
rfl
14301546

1547+
/-- `EReal.toENNReal` is multiplicative. For the version with the nonnegativity
1548+
hypothesis on the second variable, see `EReal.toENNReal_mul'`. -/
1549+
lemma toENNReal_mul {x y : EReal} (hx : 0 ≤ x) :
1550+
(x * y).toENNReal = x.toENNReal * y.toENNReal := by
1551+
induction x <;> induction y
1552+
<;> try {· simp_all [mul_nonpos_iff, ofReal_mul, ← coe_mul]}
1553+
· rcases eq_or_lt_of_le hx with (hx | hx)
1554+
· simp [← hx]
1555+
· simp_all [mul_top_of_pos hx]
1556+
· rename_i a
1557+
rcases lt_trichotomy a 0 with (ha | ha | ha)
1558+
· simp_all [le_of_lt, top_mul_of_neg (EReal.coe_neg'.mpr ha)]
1559+
· simp [ha]
1560+
· simp_all [top_mul_of_pos (EReal.coe_pos.mpr ha)]
1561+
1562+
/-- `EReal.toENNReal` is multiplicative. For the version with the nonnegativity
1563+
hypothesis on the first variable, see `EReal.toENNReal_mul`. -/
1564+
lemma toENNReal_mul' {x y : EReal} (hy : 0 ≤ y) :
1565+
(x * y).toENNReal = x.toENNReal * y.toENNReal := by
1566+
rw [EReal.mul_comm, toENNReal_mul hy, mul_comm]
1567+
14311568
lemma right_distrib_of_nonneg {a b c : EReal} (ha : 0 ≤ a) (hb : 0 ≤ b) :
14321569
(a + b) * c = a * c + b * c := by
14331570
rcases eq_or_lt_of_le ha with (rfl | a_pos)
@@ -1946,4 +2083,4 @@ unsafe def positivity_coe_ennreal_ereal : expr → tactic strictness
19462083
end Tactic
19472084
-/
19482085

1949-
set_option linter.style.longFile 2000
2086+
set_option linter.style.longFile 2200

Mathlib/MeasureTheory/Constructions/BorelSpace/Real.lean

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,20 @@ theorem AEMeasurable.coe_ereal_ennreal {f : α → ℝ≥0∞} {μ : Measure α}
430430
AEMeasurable (fun x => (f x : EReal)) μ :=
431431
measurable_coe_ennreal_ereal.comp_aemeasurable hf
432432

433+
@[measurability]
434+
theorem measurable_ereal_toENNReal : Measurable EReal.toENNReal :=
435+
EReal.measurable_of_measurable_real (by simpa using ENNReal.measurable_ofReal)
436+
437+
@[measurability, fun_prop]
438+
theorem Measurable.ereal_toENNReal {f : α → EReal} (hf : Measurable f) :
439+
Measurable fun x => (f x).toENNReal :=
440+
measurable_ereal_toENNReal.comp hf
441+
442+
@[measurability, fun_prop]
443+
theorem AEMeasurable.ereal_toENNReal {f : α → EReal} {μ : Measure α} (hf : AEMeasurable f μ) :
444+
AEMeasurable (fun x => (f x).toENNReal) μ :=
445+
measurable_ereal_toENNReal.comp_aemeasurable hf
446+
433447
namespace NNReal
434448

435449
instance : MeasurableSMul₂ ℝ≥0 ℝ≥0where

Mathlib/Topology/Instances/EReal.lean

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,50 @@ lemma tendsto_toReal_atBot : Tendsto EReal.toReal (𝓝[≠] ⊥) atBot := by
193193
rw [nhdsWithin_bot, tendsto_map'_iff]
194194
exact tendsto_id
195195

196+
/-! ### toENNReal -/
197+
198+
lemma continuous_toENNReal : Continuous EReal.toENNReal := by
199+
refine continuous_iff_continuousAt.mpr fun x ↦ ?_
200+
by_cases h_top : x = ⊤
201+
· simp only [ContinuousAt, h_top, toENNReal_top]
202+
refine ENNReal.tendsto_nhds_top fun n ↦ ?_
203+
filter_upwards [eventually_gt_nhds (coe_lt_top n)] with y hy
204+
exact toENNReal_coe (x := n) ▸ toENNReal_lt_toENNReal (coe_ennreal_nonneg _) hy
205+
refine ContinuousOn.continuousAt ?_ (compl_singleton_mem_nhds_iff.mpr h_top)
206+
refine (continuousOn_of_forall_continuousAt fun x hx ↦ ?_).congr (fun _ h ↦ toENNReal_of_ne_top h)
207+
by_cases h_bot : x = ⊥
208+
· refine tendsto_nhds_of_eventually_eq ?_
209+
rw [h_bot, nhds_bot_basis.eventually_iff]
210+
simp [toReal_bot, ENNReal.ofReal_zero, ENNReal.ofReal_eq_zero, true_and]
211+
exact ⟨0, fun _ hx ↦ toReal_nonpos hx.le⟩
212+
refine ENNReal.continuous_ofReal.continuousAt.comp' <| continuousOn_toReal.continuousAt
213+
<| (toFinite _).isClosed.compl_mem_nhds ?_
214+
simp_all only [mem_compl_iff, mem_singleton_iff, mem_insert_iff, or_self, not_false_eq_true]
215+
216+
@[fun_prop]
217+
lemma _root_.Continous.ereal_toENNReal {α : Type*} [TopologicalSpace α] {f : α → EReal}
218+
(hf : Continuous f) :
219+
Continuous fun x => (f x).toENNReal :=
220+
continuous_toENNReal.comp hf
221+
222+
@[fun_prop]
223+
lemma _root_.ContinuousOn.ereal_toENNReal {α : Type*} [TopologicalSpace α] {s : Set α}
224+
{f : α → EReal} (hf : ContinuousOn f s) :
225+
ContinuousOn (fun x => (f x).toENNReal) s :=
226+
continuous_toENNReal.comp_continuousOn hf
227+
228+
@[fun_prop]
229+
lemma _root_.ContinuousWithinAt.ereal_toENNReal {α : Type*} [TopologicalSpace α] {f : α → EReal}
230+
{s : Set α} {x : α} (hf : ContinuousWithinAt f s x) :
231+
ContinuousWithinAt (fun x => (f x).toENNReal) s x :=
232+
continuous_toENNReal.continuousAt.comp_continuousWithinAt hf
233+
234+
@[fun_prop]
235+
lemma _root_.ContinuousAt.ereal_toENNReal {α : Type*} [TopologicalSpace α] {f : α → EReal}
236+
{x : α} (hf : ContinuousAt f x) :
237+
ContinuousAt (fun x => (f x).toENNReal) x :=
238+
continuous_toENNReal.continuousAt.comp hf
239+
196240
/-! ### Infs and Sups -/
197241

198242
variable {α : Type*} {u v : α → EReal}

0 commit comments

Comments
 (0)