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

Commit c435b1c

Browse files
urkudkim-em
andcommitted
feat(analysis/calculus/inverse): Inverse function theorem (#2228)
Ref #1849 Co-authored-by: Scott Morrison <scott@tqft.net>
1 parent 3c02800 commit c435b1c

File tree

8 files changed

+644
-6
lines changed

8 files changed

+644
-6
lines changed

src/analysis/asymptotics.lean

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ lemma is_o.def {f : α → E} {g : α → F} {l : filter α} (h : is_o f g l) {c
113113
∀ᶠ x in l, ∥ f x ∥ ≤ c * ∥ g x ∥ :=
114114
h hc
115115

116+
lemma is_o.def' {f : α → E} {g : α → F} {l : filter α} (h : is_o f g l) {c : ℝ} (hc : 0 < c) :
117+
is_O_with c f g l :=
118+
h hc
119+
116120
end defs
117121

118122
/-! ### Conversions -/
@@ -1034,9 +1038,17 @@ end
10341038

10351039
theorem is_O_with.right_le_add_of_lt_1 {f₁ f₂ : α → E'} (h : is_O_with c f₁ f₂ l) (hc : c < 1) :
10361040
is_O_with (1 / (1 - c)) f₂ (λx, f₁ x + f₂ x) l :=
1037-
(h.neg_right.right_le_sub_of_lt_1 hc).neg_right.neg_left.congr rfl (λ x, neg_neg _)
1041+
(h.neg_right.right_le_sub_of_lt_1 hc).neg_right.of_neg_left.congr rfl (λ x, rfl)
10381042
(λ x, by rw [neg_sub, sub_neg_eq_add])
10391043

1044+
theorem is_o.right_is_O_sub {f₁ f₂ : α → E'} (h : is_o f₁ f₂ l) :
1045+
is_O f₂ (λx, f₂ x - f₁ x) l :=
1046+
((h.def' one_half_pos).right_le_sub_of_lt_1 one_half_lt_one).is_O
1047+
1048+
theorem is_o.right_is_O_add {f₁ f₂ : α → E'} (h : is_o f₁ f₂ l) :
1049+
is_O f₂ (λx, f₁ x + f₂ x) l :=
1050+
((h.def' one_half_pos).right_le_add_of_lt_1 one_half_lt_one).is_O
1051+
10401052
end asymptotics
10411053

10421054
namespace local_homeomorph

src/analysis/calculus/deriv.lean

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ We also show the existence and compute the derivatives of:
5555
- multiplication of a function in `𝕜 → 𝕜` and of a function in `𝕜 → E`
5656
- composition of a function in `𝕜 → F` with a function in `𝕜 → 𝕜`
5757
- composition of a function in `F → E` with a function in `𝕜 → F`
58+
- inverse function (assuming that it exists; the inverse function theorem is in `inverse.lean`)
5859
- division
5960
- polynomials
6061
@@ -1263,6 +1264,42 @@ lemma deriv_within_div
12631264
((hc.has_deriv_at).div (hd.has_deriv_at) hx).deriv
12641265

12651266
end division
1267+
1268+
theorem has_strict_deriv_at.has_strict_fderiv_at_equiv {f : 𝕜 → 𝕜} {f' x : 𝕜}
1269+
(hf : has_strict_deriv_at f f' x) (hf' : f' ≠ 0) :
1270+
has_strict_fderiv_at f
1271+
(continuous_linear_equiv.units_equiv_aut 𝕜 (units.mk0 f' hf') : 𝕜 →L[𝕜] 𝕜) x :=
1272+
hf
1273+
1274+
theorem has_deriv_at.has_fderiv_at_equiv {f : 𝕜 → 𝕜} {f' x : 𝕜}
1275+
(hf : has_deriv_at f f' x) (hf' : f' ≠ 0) :
1276+
has_fderiv_at f
1277+
(continuous_linear_equiv.units_equiv_aut 𝕜 (units.mk0 f' hf') : 𝕜 →L[𝕜] 𝕜) x :=
1278+
hf
1279+
1280+
/-- If `f (g y) = y` for `y` in some neighborhood of `a`, `g` is continuous at `a`, and `f` has an
1281+
invertible derivative `f'` at `g a` in the strict sense, then `g` has the derivative `f'⁻¹` at `a`
1282+
in the strict sense.
1283+
1284+
This is one of the easy parts of the inverse function theorem: it assumes that we already have an
1285+
inverse function. -/
1286+
theorem has_strict_deriv_at.of_local_left_inverse {f g : 𝕜 → 𝕜} {f' a : 𝕜}
1287+
(hg : continuous_at g a) (hf : has_strict_deriv_at f f' (g a)) (hf' : f' ≠ 0)
1288+
(hfg : ∀ᶠ y in 𝓝 a, f (g y) = y) :
1289+
has_strict_deriv_at g f'⁻¹ a :=
1290+
(hf.has_strict_fderiv_at_equiv hf').of_local_left_inverse hg hfg
1291+
1292+
/-- If `f (g y) = y` for `y` in some neighborhood of `a`, `g` is continuous at `a`, and `f` has an
1293+
invertible derivative `f'` at `g a`, then `g` has the derivative `f'⁻¹` at `a`.
1294+
1295+
This is one of the easy parts of the inverse function theorem: it assumes that we already have
1296+
an inverse function. -/
1297+
theorem has_deriv_at.of_local_left_inverse {f g : 𝕜 → 𝕜} {f' a : 𝕜}
1298+
(hg : continuous_at g a) (hf : has_deriv_at f f' (g a)) (hf' : f' ≠ 0)
1299+
(hfg : ∀ᶠ y in 𝓝 a, f (g y) = y) :
1300+
has_deriv_at g f'⁻¹ a :=
1301+
(hf.has_fderiv_at_equiv hf').of_local_left_inverse hg hfg
1302+
12661303
end
12671304

12681305
namespace polynomial

src/analysis/calculus/fderiv.lean

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ usual formulas (and existence assertions) for the derivative of
4343
* multiplication of a function by a scalar function
4444
* multiplication of two scalar functions
4545
* composition of functions (the chain rule)
46+
* inverse function (assuming that it exists; the inverse function theorem is in `inverse.lean`)
4647
4748
For most binary operations we also define `const_op` and `op_const` theorems for the cases when
4849
the first or second argument is a constant. This makes writing chains of `has_deriv_at`'s easier,
@@ -346,14 +347,14 @@ lemma has_fderiv_at_filter.is_O_sub (h : has_fderiv_at_filter f f' x L) :
346347
is_O (λ x', f x' - f x) (λ x', x' - x) L :=
347348
h.is_O.congr_of_sub.2 (f'.is_O_sub _ _)
348349

349-
lemma has_strict_fderiv_at.has_fderiv_at (hf : has_strict_fderiv_at f f' x) :
350+
protected lemma has_strict_fderiv_at.has_fderiv_at (hf : has_strict_fderiv_at f f' x) :
350351
has_fderiv_at f f' x :=
351352
begin
352353
rw [has_fderiv_at, has_fderiv_at_filter, is_o_iff],
353354
exact (λ c hc, tendsto_id.prod_mk_nhds tendsto_const_nhds (is_o_iff.1 hf hc))
354355
end
355356

356-
lemma has_strict_fderiv_at.differentiable_at (hf : has_strict_fderiv_at f f' x) :
357+
protected lemma has_strict_fderiv_at.differentiable_at (hf : has_strict_fderiv_at f f' x) :
357358
differentiable_at 𝕜 f x :=
358359
hf.has_fderiv_at.differentiable_at
359360

@@ -563,10 +564,22 @@ lemma differentiable_on.continuous_on (h : differentiable_on 𝕜 f s) : continu
563564
lemma differentiable.continuous (h : differentiable 𝕜 f) : continuous f :=
564565
continuous_iff_continuous_at.2 $ λx, (h x).continuous_at
565566

566-
lemma has_strict_fderiv_at.continuous_at (hf : has_strict_fderiv_at f f' x) :
567+
protected lemma has_strict_fderiv_at.continuous_at (hf : has_strict_fderiv_at f f' x) :
567568
continuous_at f x :=
568569
hf.has_fderiv_at.continuous_at
569570

571+
lemma has_strict_fderiv_at.is_O_sub_rev {f' : E ≃L[𝕜] F}
572+
(hf : has_strict_fderiv_at f (f' : E →L[𝕜] F) x) :
573+
is_O (λ p : E × E, p.1 - p.2) (λ p : E × E, f p.1 - f p.2) (𝓝 (x, x)) :=
574+
((f'.is_O_comp_rev _ _).trans (hf.trans_is_O (f'.is_O_comp_rev _ _)).right_is_O_add).congr
575+
(λ _, rfl) (λ _, sub_add_cancel _ _)
576+
577+
lemma has_fderiv_at_filter.is_O_sub_rev {f' : E ≃L[𝕜] F}
578+
(hf : has_fderiv_at_filter f (f' : E →L[𝕜] F) x L) :
579+
is_O (λ x', x' - x) (λ x', f x' - f x) L :=
580+
((f'.is_O_sub_rev _ _).trans (hf.trans_is_O (f'.is_O_sub_rev _ _)).right_is_O_add).congr
581+
(λ _, rfl) (λ _, sub_add_cancel _ _)
582+
570583
end continuous
571584

572585
section congr
@@ -980,7 +993,7 @@ lemma differentiable.comp_differentiable_on {g : F → G} (hg : differentiable
980993
(differentiable_on_univ.2 hg).comp hf (by simp)
981994

982995
/-- The chain rule for derivatives in the sense of strict differentiability. -/
983-
lemma has_strict_fderiv_at.comp {g : F → G} {g' : F →L[𝕜] G}
996+
protected lemma has_strict_fderiv_at.comp {g : F → G} {g' : F →L[𝕜] G}
984997
(hg : has_strict_fderiv_at g g' (f x)) (hf : has_strict_fderiv_at f f' x) :
985998
has_strict_fderiv_at (λ x, g (f x)) (g'.comp f') x :=
986999
((hg.comp_tendsto (hf.continuous_at.prod_map' hf.continuous_at)).trans_is_O hf.is_O_sub).triangle $
@@ -994,7 +1007,7 @@ section cartesian_product
9941007
section prod
9951008
variables {f₂ : E → G} {f₂' : E →L[𝕜] G}
9961009

997-
lemma has_strict_fderiv_at.prod
1010+
protected lemma has_strict_fderiv_at.prod
9981011
(hf₁ : has_strict_fderiv_at f₁ f₁' x) (hf₂ : has_strict_fderiv_at f₂ f₂' x) :
9991012
has_strict_fderiv_at (λx, (f₁ x, f₂ x)) (continuous_linear_map.prod f₁' f₂') x :=
10001013
hf₁.prod_left hf₂
@@ -2064,6 +2077,58 @@ end
20642077

20652078
end continuous_linear_equiv
20662079

2080+
/-- If `f (g y) = y` for `y` in some neighborhood of `a`, `g` is continuous at `a`, and `f` has an
2081+
invertible derivative `f'` at `g a` in the strict sense, then `g` has the derivative `f'⁻¹` at `a`
2082+
in the strict sense.
2083+
2084+
This is one of the easy parts of the inverse function theorem: it assumes that we already have an
2085+
inverse function. -/
2086+
theorem has_strict_fderiv_at.of_local_left_inverse {f : E → F} {f' : E ≃L[𝕜] F} {g : F → E} {a : F}
2087+
(hg : continuous_at g a) (hf : has_strict_fderiv_at f (f' : E →L[𝕜] F) (g a))
2088+
(hfg : ∀ᶠ y in 𝓝 a, f (g y) = y) :
2089+
has_strict_fderiv_at g (f'.symm : F →L[𝕜] E) a :=
2090+
begin
2091+
replace hg := hg.prod_map' hg,
2092+
replace hfg := hfg.prod_mk_nhds hfg,
2093+
have : is_O (λ p : F × F, g p.1 - g p.2 - f'.symm (p.1 - p.2))
2094+
(λ p : F × F, f' (g p.1 - g p.2) - (p.1 - p.2)) (𝓝 (a, a)),
2095+
{ refine ((f'.symm : F →L[𝕜] E).is_O_comp _ _).congr (λ x, _) (λ _, rfl),
2096+
simp },
2097+
refine this.trans_is_o _, clear this,
2098+
refine ((hf.comp_tendsto hg).symm.congr' (hfg.mono _)
2099+
(eventually_of_forall _ $ λ _, rfl)).trans_is_O _,
2100+
{ rintros p ⟨hp1, hp2⟩,
2101+
simp [hp1, hp2] },
2102+
{ refine (hf.is_O_sub_rev.comp_tendsto hg).congr'
2103+
(eventually_of_forall _ $ λ _, rfl) (hfg.mono _),
2104+
rintros p ⟨hp1, hp2⟩,
2105+
simp only [(∘), hp1, hp2] }
2106+
end
2107+
2108+
/-- If `f (g y) = y` for `y` in some neighborhood of `a`, `g` is continuous at `a`, and `f` has an
2109+
invertible derivative `f'` at `g a`, then `g` has the derivative `f'⁻¹` at `a`.
2110+
2111+
This is one of the easy parts of the inverse function theorem: it assumes that we already have
2112+
an inverse function. -/
2113+
theorem has_fderiv_at.of_local_left_inverse {f : E → F} {f' : E ≃L[𝕜] F} {g : F → E} {a : F}
2114+
(hg : continuous_at g a) (hf : has_fderiv_at f (f' : E →L[𝕜] F) (g a))
2115+
(hfg : ∀ᶠ y in 𝓝 a, f (g y) = y) :
2116+
has_fderiv_at g (f'.symm : F →L[𝕜] E) a :=
2117+
begin
2118+
have : is_O (λ x : F, g x - g a - f'.symm (x - a)) (λ x : F, f' (g x - g a) - (x - a)) (𝓝 a),
2119+
{ refine ((f'.symm : F →L[𝕜] E).is_O_comp _ _).congr (λ x, _) (λ _, rfl),
2120+
simp },
2121+
refine this.trans_is_o _, clear this,
2122+
refine ((hf.comp_tendsto hg).symm.congr' (hfg.mono _)
2123+
(eventually_of_forall _ $ λ _, rfl)).trans_is_O _,
2124+
{ rintros p hp,
2125+
simp [hp, hfg.self_of_nhds] },
2126+
{ refine (hf.is_O_sub_rev.comp_tendsto hg).congr'
2127+
(eventually_of_forall _ $ λ _, rfl) (hfg.mono _),
2128+
rintros p hp,
2129+
simp only [(∘), hp, hfg.self_of_nhds] }
2130+
end
2131+
20672132
end
20682133

20692134
section

0 commit comments

Comments
 (0)