Skip to content

Commit f4d59b3

Browse files
committed
feat(Analysis/Calculus/Deriv/Inverse): add deriv_zero_of_frequently_mem (leanprover-community#34576)
This PR proves that if a function frequently (in `𝓝[s ∖ {x}]`) takes values in a set `t` that does not accumulate at `f x`, then its derivative at `x` equals zero. The application that I have in mind is where this set is closed and discrete (and thus has no accumulation points). Co-authored-by: tb65536 <thomas.l.browning@gmail.com>
1 parent 32a03d8 commit f4d59b3

2 files changed

Lines changed: 72 additions & 15 deletions

File tree

Mathlib/Analysis/Calculus/Deriv/Inverse.lean

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,32 @@ theorem OpenPartialHomeomorph.hasDerivAt_symm (f : OpenPartialHomeomorph 𝕜
8989
HasDerivAt f.symm f'⁻¹ a :=
9090
htff'.of_local_left_inverse (f.symm.continuousAt ha) hf' (f.eventually_right_inverse ha)
9191

92+
theorem HasDerivWithinAt.tendsto_nhdsWithin_nhdsNE (h : HasDerivWithinAt f f' s x) (hf' : f' ≠ 0) :
93+
Tendsto f (𝓝[s \ {x}] x) (𝓝[≠] f x) :=
94+
h.hasFDerivWithinAt.tendsto_nhdsWithin_nhdsNE ⟨‖f'‖₊⁻¹, AntilipschitzWith.of_le_mul_dist
95+
fun _ _ ↦ by simp [dist_eq_norm_sub, ← sub_smul, norm_smul]; field_simp; rfl⟩
96+
9297
theorem HasDerivWithinAt.eventually_ne (h : HasDerivWithinAt f f' s x) (hf' : f' ≠ 0) :
9398
∀ᶠ z in 𝓝[s \ {x}] x, f z ≠ c :=
94-
h.hasFDerivWithinAt.eventually_ne
95-
⟨‖f'‖⁻¹, fun z => by simp [norm_smul]; field_simp; rfl⟩
99+
h.hasFDerivWithinAt.eventually_ne ⟨‖f'‖₊⁻¹, AntilipschitzWith.of_le_mul_dist
100+
fun _ _ ↦ by simp [dist_eq_norm_sub, ← sub_smul, norm_smul]; field_simp; rfl⟩
101+
102+
theorem HasDerivWithinAt.eventually_notMem (h : HasDerivWithinAt f f' s x) (hf' : f' ≠ 0)
103+
(t : Set F) (ht : ¬ AccPt (f x) (𝓟 t)) : ∀ᶠ z in 𝓝[s \ {x}] x, f z ∉ t :=
104+
h.hasFDerivWithinAt.eventually_notMem ⟨‖f'‖₊⁻¹, AntilipschitzWith.of_le_mul_dist
105+
fun _ _ ↦ by simp [dist_eq_norm_sub, ← sub_smul, norm_smul]; field_simp; rfl⟩ t ht
106+
107+
theorem HasDerivAt.tendsto_nhdsNE (h : HasDerivAt f f' x) (hf' : f' ≠ 0) :
108+
Tendsto f (𝓝[≠] x) (𝓝[≠] f x) := by
109+
simpa only [compl_eq_univ_diff] using (hasDerivWithinAt_univ.2 h).tendsto_nhdsWithin_nhdsNE hf'
96110

97111
theorem HasDerivAt.eventually_ne (h : HasDerivAt f f' x) (hf' : f' ≠ 0) :
98112
∀ᶠ z in 𝓝[≠] x, f z ≠ c := by
99113
simpa only [compl_eq_univ_diff] using (hasDerivWithinAt_univ.2 h).eventually_ne hf'
100114

101-
theorem HasDerivAt.tendsto_nhdsNE (h : HasDerivAt f f' x) (hf' : f' ≠ 0) :
102-
Tendsto f (𝓝[≠] x) (𝓝[≠] f x) :=
103-
tendsto_nhdsWithin_of_tendsto_nhds_of_eventually_within _ h.continuousAt.continuousWithinAt
104-
(h.eventually_ne hf')
115+
theorem HasDerivAt.eventually_notMem (h : HasDerivAt f f' x) (hf' : f' ≠ 0)
116+
(t : Set F) (ht : ¬ AccPt (f x) (𝓟 t)) : ∀ᶠ z in 𝓝[≠] x, f z ∉ t := by
117+
simpa only [compl_eq_univ_diff] using (hasDerivWithinAt_univ.2 h).eventually_notMem hf' t ht
105118

106119
/-- If a function is equal to a constant at a set of points that accumulates to `x` in `s`,
107120
then its derivative within `s` at `x` equals zero,
@@ -113,13 +126,31 @@ theorem derivWithin_zero_of_frequently_const {c} (h : ∃ᶠ y in 𝓝[s \ {x}]
113126
exact hf.hasDerivWithinAt.eventually_ne h
114127
· exact derivWithin_zero_of_not_differentiableWithinAt hf
115128

129+
/-- If a function frequently (in `𝓝[s ∖ {x}] x`) takes values in a set `t` that does not
130+
accumulate at `f x`, then its derivative within `s` at `x` equals zero,
131+
either because it has derivative zero or because it isn't differentiable at this point. -/
132+
theorem derivWithin_zero_of_frequently_mem (t : Set F) (ht : ¬ AccPt (f x) (𝓟 t))
133+
(h : ∃ᶠ y in 𝓝[s \ {x}] x, f y ∈ t) : derivWithin f s x = 0 := by
134+
by_cases hf : DifferentiableWithinAt 𝕜 f s x
135+
· contrapose! h
136+
exact hf.hasDerivWithinAt.eventually_notMem h t ht
137+
· exact derivWithin_zero_of_not_differentiableWithinAt hf
138+
116139
/-- If a function is equal to a constant at a set of points that accumulates to `x`,
117140
then its derivative at `x` equals zero,
118141
either because it has derivative zero or because it isn't differentiable at this point. -/
119142
theorem deriv_zero_of_frequently_const {c} (h : ∃ᶠ y in 𝓝[≠] x, f y = c) : deriv f x = 0 := by
120143
rw [← derivWithin_univ, derivWithin_zero_of_frequently_const]
121144
rwa [← compl_eq_univ_diff]
122145

146+
/-- If a function frequently (in `𝓝[≠] x`) takes values in a set `t` that does not
147+
accumulate at `f x`, then its derivative at `x` equals zero,
148+
either because it has derivative zero or because it isn't differentiable at this point. -/
149+
theorem deriv_zero_of_frequently_mem (t : Set F) (ht : ¬ AccPt (f x) (𝓟 t))
150+
(h : ∃ᶠ y in 𝓝[≠] x, f y ∈ t) : deriv f x = 0 := by
151+
rw [← derivWithin_univ, derivWithin_zero_of_frequently_mem t ht]
152+
rwa [← compl_eq_univ_diff]
153+
123154
theorem not_differentiableWithinAt_of_local_left_inverse_hasDerivWithinAt_zero {f g : 𝕜 → 𝕜} {a : 𝕜}
124155
{s t : Set 𝕜} (ha : a ∈ s) (hsu : UniqueDiffWithinAt 𝕜 s a) (hf : HasDerivWithinAt f 0 t (g a))
125156
(hst : MapsTo g s t) (hfg : f ∘ g =ᶠ[𝓝[s] a] id) : ¬DifferentiableWithinAt 𝕜 g s a := by

Mathlib/Analysis/Calculus/FDeriv/Equiv.lean

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -404,20 +404,46 @@ theorem OpenPartialHomeomorph.hasFDerivAt_symm (f : OpenPartialHomeomorph E F) {
404404
HasFDerivAt f.symm (f'.symm : F →L[𝕜] E) a :=
405405
htff'.of_local_left_inverse (f.symm.continuousAt ha) (f.eventually_right_inverse ha)
406406

407+
theorem HasFDerivWithinAt.tendsto_nhdsWithin_nhdsNE (h : HasFDerivWithinAt f f' s x)
408+
(hf' : ∃ C, AntilipschitzWith C f') : Tendsto f (𝓝[s \ {x}] x) (𝓝[≠] f x) := by
409+
replace hf' : ∃ C, ∀ z, ‖z‖ ≤ C * ‖f' z‖ := by
410+
obtain ⟨C, hC⟩ := hf'
411+
exact ⟨C, fun x ↦ by simpa using hC.le_mul_dist 0 x⟩
412+
have A : (fun z ↦ z - x) =O[𝓝[s] x] fun z ↦ f' (z - x) :=
413+
isBigO_iff.mpr <| hf'.imp fun C hC ↦ Eventually.of_forall fun z ↦ hC (z - x)
414+
have : (fun z ↦ f z - f x) ~[𝓝[s] x] fun z ↦ f' (z - x) := h.isLittleO.trans_isBigO A
415+
have : ∀ᶠ (x_1 : E) in 𝓝[s] x, x_1 ∈ ({x}ᶜ : Set E) → f x_1 ∈ ({f x}ᶜ : Set F) := by
416+
simpa [sub_eq_zero, not_imp_not] using (A.trans this.isBigO_symm).eq_zero_imp
417+
apply le_inf ((map_mono (nhdsWithin_mono x diff_subset)).trans h.continuousWithinAt)
418+
rwa [le_principal_iff, ← eventually_mem_set, eventually_map, diff_eq, nhdsWithin_inter',
419+
eventually_inf_principal]
420+
407421
theorem HasFDerivWithinAt.eventually_ne (h : HasFDerivWithinAt f f' s x)
408-
(hf' : ∃ C, ∀ z, ‖z‖ ≤ C * ‖f' z‖) : ∀ᶠ z in 𝓝[s \ {x}] x, f z ≠ c := by
422+
(hf' : ∃ C, AntilipschitzWith C f') : ∀ᶠ z in 𝓝[s \ {x}] x, f z ≠ c := by
423+
rw [← eventually_map (m := f) (P := fun z ↦ z ≠ c)]
424+
apply Eventually.filter_mono (h.tendsto_nhdsWithin_nhdsNE hf')
409425
rcases eq_or_ne (f x) c with rfl | hc
410-
· rw [nhdsWithin, diff_eq, ← inf_principal, ← inf_assoc, eventually_inf_principal]
411-
have A : (fun z => z - x) =O[𝓝[s] x] fun z => f' (z - x) :=
412-
isBigO_iff.2 <| hf'.imp fun C hC => Eventually.of_forall fun z => hC _
413-
have : (fun z => f z - f x) ~[𝓝[s] x] fun z => f' (z - x) := h.isLittleO.trans_isBigO A
414-
simpa [not_imp_not, sub_eq_zero] using (A.trans this.isBigO_symm).eq_zero_imp
415-
· exact (h.continuousWithinAt.eventually_ne hc).filter_mono <| by gcongr; apply diff_subset
416-
417-
theorem HasFDerivAt.eventually_ne (h : HasFDerivAt f f' x) (hf' : ∃ C, ∀ z, ‖z‖ ≤ C * ‖f' z‖) :
426+
· exact eventually_mem_nhdsWithin
427+
· exact eventually_ne_nhdsWithin hc
428+
429+
theorem HasFDerivWithinAt.eventually_notMem (h : HasFDerivWithinAt f f' s x)
430+
(hf' : ∃ C, AntilipschitzWith C f') (t : Set F) (ht : ¬ AccPt (f x) (𝓟 t)) :
431+
∀ᶠ z in 𝓝[s \ {x}] x, f z ∉ t := by
432+
rw [accPt_iff_frequently_nhdsNE, not_frequently] at ht
433+
exact eventually_map.mp (ht.filter_mono (h.tendsto_nhdsWithin_nhdsNE hf'))
434+
435+
theorem HasFDerivAt.tendsto_nhdsNE (h : HasFDerivAt f f' x)
436+
(hf' : ∃ C, AntilipschitzWith C f') : Tendsto f (𝓝[≠] x) (𝓝[≠] f x) := by
437+
simpa only [compl_eq_univ_diff] using (hasFDerivWithinAt_univ.2 h).tendsto_nhdsWithin_nhdsNE hf'
438+
439+
theorem HasFDerivAt.eventually_ne (h : HasFDerivAt f f' x) (hf' : ∃ C, AntilipschitzWith C f') :
418440
∀ᶠ z in 𝓝[≠] x, f z ≠ c := by
419441
simpa only [compl_eq_univ_diff] using (hasFDerivWithinAt_univ.2 h).eventually_ne hf'
420442

443+
theorem HasFDerivAt.eventually_notMem (h : HasFDerivAt f f' x) (hf' : ∃ C, AntilipschitzWith C f')
444+
(t : Set F) (ht : ¬ AccPt (f x) (𝓟 t)) : ∀ᶠ z in 𝓝[≠] x, f z ∉ t := by
445+
simpa only [compl_eq_univ_diff] using (hasFDerivWithinAt_univ.2 h).eventually_notMem hf' t ht
446+
421447
end
422448

423449
section

0 commit comments

Comments
 (0)