Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit ed0ae3e

Browse files
committed
feat(analysis/calculus/inverse): a map that has an invertible strict derivative at every point is an open map (#5753)
More generally, the same is true for a map that is a local homeomorphism near every point.
1 parent 4c1d12f commit ed0ae3e

File tree

4 files changed

+47
-16
lines changed

4 files changed

+47
-16
lines changed

src/analysis/calculus/inverse.lean

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,9 @@ lemma image_mem_to_local_homeomorph_target (hf : has_strict_fderiv_at f (f' : E
415415
f a ∈ (hf.to_local_homeomorph f).target :=
416416
(hf.to_local_homeomorph f).map_source hf.mem_to_local_homeomorph_source
417417

418+
lemma map_nhds_eq (hf : has_strict_fderiv_at f (f' : E →L[𝕜] F) a) : map f (𝓝 a) = 𝓝 (f a) :=
419+
(hf.to_local_homeomorph f).map_nhds_eq hf.mem_to_local_homeomorph_source
420+
418421
variables (f f' a)
419422

420423
/-- Given a function `f` with an invertible derivative, returns a function that is locally inverse
@@ -473,6 +476,12 @@ hf.to_local_inverse.congr_of_eventually_eq $ (hf.local_inverse_unique hg).mono $
473476

474477
end has_strict_fderiv_at
475478

479+
/-- If a function has an invertible strict derivative at all points, then it is an open map. -/
480+
lemma open_map_of_strict_fderiv [complete_space E] {f : E → F} {f' : E → E ≃L[𝕜] F}
481+
(hf : ∀ x, has_strict_fderiv_at f (f' x : E →L[𝕜] F) x) :
482+
is_open_map f :=
483+
is_open_map_iff_nhds_le.2 $ λ x, (hf x).map_nhds_eq.ge
484+
476485
/-!
477486
### Inverse function theorem, 1D case
478487
@@ -496,6 +505,9 @@ variables (f f' a)
496505

497506
variables {f f' a}
498507

508+
lemma map_nhds_eq : map f (𝓝 a) = 𝓝 (f a) :=
509+
(hf.has_strict_fderiv_at_equiv hf').map_nhds_eq
510+
499511
theorem to_local_inverse : has_strict_deriv_at (hf.local_inverse f f' a hf') f'⁻¹ (f a) :=
500512
(hf.has_strict_fderiv_at_equiv hf').to_local_inverse
501513

@@ -505,6 +517,12 @@ theorem to_local_left_inverse {g : 𝕜 → 𝕜} (hg : ∀ᶠ x in 𝓝 a, g (f
505517

506518
end has_strict_deriv_at
507519

520+
/-- If a function has a non-zero strict derivative at all points, then it is an open map. -/
521+
lemma open_map_of_strict_deriv [complete_space 𝕜] {f f' : 𝕜 → 𝕜}
522+
(hf : ∀ x, has_strict_deriv_at f (f' x) x) (h0 : ∀ x, f' x ≠ 0) :
523+
is_open_map f :=
524+
is_open_map_iff_nhds_le.2 $ λ x, ((hf x).map_nhds_eq (h0 x)).ge
525+
508526
/-!
509527
### Inverse function theorem, smooth case
510528

src/order/filter/basic.lean

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1318,6 +1318,8 @@ iff.intro
13181318
@[simp] lemma map_id : filter.map id f = f :=
13191319
filter_eq $ rfl
13201320

1321+
@[simp] lemma map_id' : filter.map (λ x, x) f = f := map_id
1322+
13211323
@[simp] lemma map_compose : filter.map m' ∘ filter.map m = filter.map (m' ∘ m) :=
13221324
funext $ assume _, filter_eq $ rfl
13231325

@@ -1773,7 +1775,7 @@ le_antisymm
17731775
lemma map_swap_eq_comap_swap {f : filter (α × β)} : prod.swap <$> f = comap prod.swap f :=
17741776
map_eq_comap_of_inverse prod.swap_swap_eq prod.swap_swap_eq
17751777

1776-
lemma le_map {f : filter α} {m : α → β} {g : filter β} (h : ∀s∈ f, m '' s ∈ g) :
1778+
lemma le_map {f : filter α} {m : α → β} {g : filter β} (h : ∀ s ∈ f, m '' s ∈ g) :
17771779
g ≤ f.map m :=
17781780
assume s hs, mem_sets_of_superset (h _ hs) $ image_preimage_subset _ _
17791781

@@ -2024,6 +2026,11 @@ mt hf.eventually h
20242026
@[simp] lemma tendsto_bot {f : α → β} {l : filter β} : tendsto f ⊥ l := by simp [tendsto]
20252027
@[simp] lemma tendsto_top {f : α → β} {l : filter α} : tendsto f l ⊤ := le_top
20262028

2029+
lemma le_map_of_right_inverse {mab : α → β} {mba : β → α} {f : filter α} {g : filter β}
2030+
(h₁ : mab ∘ mba =ᶠ[g] id) (h₂ : tendsto mba g f) :
2031+
g ≤ map mab f :=
2032+
by { rw [← @map_id _ g, ← map_congr h₁, ← map_map], exact map_mono h₂ }
2033+
20272034
lemma tendsto_of_not_nonempty {f : α → β} {la : filter α} {lb : filter β} (h : ¬nonempty α) :
20282035
tendsto f la lb :=
20292036
by simp only [filter_eq_bot_of_not_nonempty la h, tendsto_bot]

src/topology/local_homeomorph.lean

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ especially when restricting to subsets, as these should be open subsets.
3737
For design notes, see `local_equiv.lean`.
3838
-/
3939

40-
open function set
40+
open function set filter
4141
open_locale topological_space
4242

4343
variables {α : Type*} {β : Type*} {γ : Type*} {δ : Type*}
@@ -121,15 +121,15 @@ end
121121

122122
lemma eventually_left_inverse (e : local_homeomorph α β) {x} (hx : x ∈ e.source) :
123123
∀ᶠ y in 𝓝 x, e.symm (e y) = y :=
124-
filter.eventually.mono (mem_nhds_sets e.open_source hx) e.left_inv'
124+
(e.open_source.eventually_mem hx).mono e.left_inv'
125125

126126
lemma eventually_left_inverse' (e : local_homeomorph α β) {x} (hx : x ∈ e.target) :
127127
∀ᶠ y in 𝓝 (e.symm x), e.symm (e y) = y :=
128128
e.eventually_left_inverse (e.map_target hx)
129129

130130
lemma eventually_right_inverse (e : local_homeomorph α β) {x} (hx : x ∈ e.target) :
131131
∀ᶠ y in 𝓝 x, e (e.symm y) = y :=
132-
filter.eventually.mono (mem_nhds_sets e.open_target hx) e.right_inv'
132+
(e.open_target.eventually_mem hx).mono e.right_inv'
133133

134134
lemma eventually_right_inverse' (e : local_homeomorph α β) {x} (hx : x ∈ e.source) :
135135
∀ᶠ y in 𝓝 (e x), e (e.symm y) = y :=
@@ -180,9 +180,14 @@ lemma continuous_at_symm {x : β} (h : x ∈ e.target) : continuous_at e.symm x
180180
e.symm.continuous_at h
181181

182182
lemma tendsto_symm (e : local_homeomorph α β) {x} (hx : x ∈ e.source) :
183-
filter.tendsto e.symm (𝓝 (e x)) (𝓝 x) :=
183+
tendsto e.symm (𝓝 (e x)) (𝓝 x) :=
184184
by simpa only [continuous_at, e.left_inv hx] using e.continuous_at_symm (e.map_source hx)
185185

186+
lemma map_nhds_eq (e : local_homeomorph α β) {x} (hx : x ∈ e.source) :
187+
map e (𝓝 x) = 𝓝 (e x) :=
188+
le_antisymm (e.continuous_at hx) $
189+
le_map_of_right_inverse (e.eventually_right_inverse' hx) (e.tendsto_symm hx)
190+
186191
/-- Preimage of interior or interior of preimage coincide for local homeomorphisms, when restricted
187192
to the source. -/
188193
lemma preimage_interior (s : set β) :

src/topology/maps.lean

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def is_open_map [topological_space α] [topological_space β] (f : α → β) :=
205205
∀ U : set α, is_open U → is_open (f '' U)
206206

207207
namespace is_open_map
208-
variables [topological_space α] [topological_space β] [topological_space γ]
208+
variables [topological_space α] [topological_space β] [topological_space γ] {f : α → β}
209209
open function
210210

211211
protected lemma id : is_open_map (@id α) := assume s hs, by rwa [image_id]
@@ -214,24 +214,27 @@ protected lemma comp
214214
{g : β → γ} {f : α → β} (hg : is_open_map g) (hf : is_open_map f) : is_open_map (g ∘ f) :=
215215
by intros s hs; rw [image_comp]; exact hg _ (hf _ hs)
216216

217-
lemma is_open_range {f : α → β} (hf : is_open_map f) : is_open (range f) :=
217+
lemma is_open_range (hf : is_open_map f) : is_open (range f) :=
218218
by { rw ← image_univ, exact hf _ is_open_univ }
219219

220-
lemma image_mem_nhds {f : α → β} (hf : is_open_map f) {x : α} {s : set α} (hx : s ∈ 𝓝 x) :
220+
lemma image_mem_nhds (hf : is_open_map f) {x : α} {s : set α} (hx : s ∈ 𝓝 x) :
221221
f '' s ∈ 𝓝 (f x) :=
222222
let ⟨t, hts, ht, hxt⟩ := mem_nhds_sets_iff.1 hx in
223223
mem_sets_of_superset (mem_nhds_sets (hf t ht) (mem_image_of_mem _ hxt)) (image_subset _ hts)
224224

225-
lemma nhds_le {f : α → β} (hf : is_open_map f) (a : α) : 𝓝 (f a) ≤ (𝓝 a).map f :=
225+
lemma nhds_le (hf : is_open_map f) (a : α) : 𝓝 (f a) ≤ (𝓝 a).map f :=
226226
le_map $ λ s, hf.image_mem_nhds
227227

228+
lemma of_nhds_le (hf : ∀ a, 𝓝 (f a) ≤ map f (𝓝 a)) : is_open_map f :=
229+
λ s hs, is_open_iff_mem_nhds.2 $ λ b ⟨a, has, hab⟩,
230+
hab ▸ hf _ (image_mem_map $ mem_nhds_sets hs has)
231+
228232
lemma of_inverse {f : α → β} {f' : β → α}
229233
(h : continuous f') (l_inv : left_inverse f f') (r_inv : right_inverse f f') :
230234
is_open_map f :=
231235
begin
232236
assume s hs,
233-
have : f' ⁻¹' s = f '' s, by ext x; simp [mem_image_iff_of_inverse r_inv l_inv],
234-
rw ← this,
237+
rw [image_eq_preimage_of_inverse r_inv l_inv],
235238
exact hs.preimage h
236239
end
237240

@@ -253,15 +256,13 @@ end is_open_map
253256

254257
lemma is_open_map_iff_nhds_le [topological_space α] [topological_space β] {f : α → β} :
255258
is_open_map f ↔ ∀(a:α), 𝓝 (f a) ≤ (𝓝 a).map f :=
256-
begin
257-
refine ⟨λ hf, hf.nhds_le, λ h s hs, is_open_iff_mem_nhds.2 _⟩,
258-
rintros b ⟨a, ha, rfl⟩,
259-
exact h _ (filter.image_mem_map $ mem_nhds_sets hs ha)
260-
end
259+
⟨λ hf, hf.nhds_le, is_open_map.of_nhds_le⟩
261260

262261
section is_closed_map
263262
variables [topological_space α] [topological_space β]
264263

264+
/-- A map `f : α → β` is said to be a *closed map*, if the image of any closed `U : set α`
265+
is closed in `β`. -/
265266
def is_closed_map (f : α → β) := ∀ U : set α, is_closed U → is_closed (f '' U)
266267

267268
end is_closed_map

0 commit comments

Comments
 (0)