Skip to content

Commit f712a29

Browse files
committed
feat: port Analysis.SpecialFunctions.ExpDeriv (#4651)
This incorporates the changes from leanprover-community/mathlib3#19139 which haven't hit mathport yet due to mathport CI failing for a few days. (Hopefully it will succeed on the next run.)
1 parent 756d1f8 commit f712a29

File tree

2 files changed

+324
-0
lines changed

2 files changed

+324
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ import Mathlib.Analysis.SpecialFunctions.Complex.Arg
610610
import Mathlib.Analysis.SpecialFunctions.Complex.Circle
611611
import Mathlib.Analysis.SpecialFunctions.Complex.Log
612612
import Mathlib.Analysis.SpecialFunctions.Exp
613+
import Mathlib.Analysis.SpecialFunctions.ExpDeriv
613614
import Mathlib.Analysis.SpecialFunctions.Log.Base
614615
import Mathlib.Analysis.SpecialFunctions.Log.Basic
615616
import Mathlib.Analysis.SpecialFunctions.Log.Monotone
Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
/-
2+
Copyright (c) 2018 Chris Hughes. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Chris Hughes, Abhimanyu Pallavi Sudhir, Jean Lo, Calle Sönne
5+
6+
! This file was ported from Lean 3 source module analysis.special_functions.exp_deriv
7+
! leanprover-community/mathlib commit 6a5c85000ab93fe5dcfdf620676f614ba8e18c26
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.Analysis.Complex.RealDeriv
12+
13+
/-!
14+
# Complex and real exponential
15+
16+
In this file we prove that `Complex.exp` and `Real.exp` are infinitely smooth functions.
17+
18+
## Tags
19+
20+
exp, derivative
21+
-/
22+
23+
24+
noncomputable section
25+
26+
open Filter Asymptotics Set Function
27+
28+
open scoped Classical Topology
29+
30+
namespace Complex
31+
32+
variable {𝕜 : Type _} [NontriviallyNormedField 𝕜] [NormedAlgebra 𝕜 ℂ]
33+
34+
/-- The complex exponential is everywhere differentiable, with the derivative `exp x`. -/
35+
theorem hasDerivAt_exp (x : ℂ) : HasDerivAt exp (exp x) x := by
36+
rw [hasDerivAt_iff_isLittleO_nhds_zero]
37+
have : (1 : ℕ) < 2 := by norm_num
38+
refine' (IsBigO.of_bound ‖exp x‖ _).trans_isLittleO (isLittleO_pow_id this)
39+
filter_upwards [Metric.ball_mem_nhds (0 : ℂ) zero_lt_one]
40+
simp only [Metric.mem_ball, dist_zero_right, norm_pow]
41+
exact fun z hz => exp_bound_sq x z hz.le
42+
#align complex.has_deriv_at_exp Complex.hasDerivAt_exp
43+
44+
theorem differentiable_exp : Differentiable 𝕜 exp := fun x =>
45+
(hasDerivAt_exp x).differentiableAt.restrictScalars 𝕜
46+
#align complex.differentiable_exp Complex.differentiable_exp
47+
48+
theorem differentiableAt_exp {x : ℂ} : DifferentiableAt 𝕜 exp x :=
49+
differentiable_exp x
50+
#align complex.differentiable_at_exp Complex.differentiableAt_exp
51+
52+
@[simp]
53+
theorem deriv_exp : deriv exp = exp :=
54+
funext fun x => (hasDerivAt_exp x).deriv
55+
#align complex.deriv_exp Complex.deriv_exp
56+
57+
@[simp]
58+
theorem iter_deriv_exp : ∀ n : ℕ, (deriv^[n]) exp = exp
59+
| 0 => rfl
60+
| n + 1 => by rw [iterate_succ_apply, deriv_exp, iter_deriv_exp n]
61+
#align complex.iter_deriv_exp Complex.iter_deriv_exp
62+
63+
theorem contDiff_exp : ∀ {n}, ContDiff 𝕜 n exp := by
64+
-- porting note: added `@` due to `∀ {n}` weirdness above
65+
refine' @(contDiff_all_iff_nat.2 fun n => ?_)
66+
have : ContDiff ℂ (↑n) exp := by
67+
induction' n with n ihn
68+
· exact contDiff_zero.2 continuous_exp
69+
· rw [contDiff_succ_iff_deriv]
70+
use differentiable_exp
71+
rwa [deriv_exp]
72+
exact this.restrict_scalars 𝕜
73+
#align complex.cont_diff_exp Complex.contDiff_exp
74+
75+
theorem hasStrictDerivAt_exp (x : ℂ) : HasStrictDerivAt exp (exp x) x :=
76+
contDiff_exp.contDiffAt.hasStrictDerivAt' (hasDerivAt_exp x) le_rfl
77+
#align complex.has_strict_deriv_at_exp Complex.hasStrictDerivAt_exp
78+
79+
theorem hasStrictFDerivAt_exp_real (x : ℂ) : HasStrictFDerivAt exp (exp x • (1 : ℂ →L[ℝ] ℂ)) x :=
80+
(hasStrictDerivAt_exp x).complexToReal_fderiv
81+
#align complex.has_strict_fderiv_at_exp_real Complex.hasStrictFDerivAt_exp_real
82+
83+
end Complex
84+
85+
section
86+
87+
variable {𝕜 : Type _} [NontriviallyNormedField 𝕜] [NormedAlgebra 𝕜 ℂ] {f : 𝕜 → ℂ} {f' : ℂ} {x : 𝕜}
88+
{s : Set 𝕜}
89+
90+
theorem HasStrictDerivAt.cexp (hf : HasStrictDerivAt f f' x) :
91+
HasStrictDerivAt (fun x => Complex.exp (f x)) (Complex.exp (f x) * f') x :=
92+
(Complex.hasStrictDerivAt_exp (f x)).comp x hf
93+
#align has_strict_deriv_at.cexp HasStrictDerivAt.cexp
94+
95+
theorem HasDerivAt.cexp (hf : HasDerivAt f f' x) :
96+
HasDerivAt (fun x => Complex.exp (f x)) (Complex.exp (f x) * f') x :=
97+
(Complex.hasDerivAt_exp (f x)).comp x hf
98+
#align has_deriv_at.cexp HasDerivAt.cexp
99+
100+
theorem HasDerivWithinAt.cexp (hf : HasDerivWithinAt f f' s x) :
101+
HasDerivWithinAt (fun x => Complex.exp (f x)) (Complex.exp (f x) * f') s x :=
102+
(Complex.hasDerivAt_exp (f x)).comp_hasDerivWithinAt x hf
103+
#align has_deriv_within_at.cexp HasDerivWithinAt.cexp
104+
105+
theorem derivWithin_cexp (hf : DifferentiableWithinAt 𝕜 f s x) (hxs : UniqueDiffWithinAt 𝕜 s x) :
106+
derivWithin (fun x => Complex.exp (f x)) s x = Complex.exp (f x) * derivWithin f s x :=
107+
hf.hasDerivWithinAt.cexp.derivWithin hxs
108+
#align deriv_within_cexp derivWithin_cexp
109+
110+
@[simp]
111+
theorem deriv_cexp (hc : DifferentiableAt 𝕜 f x) :
112+
deriv (fun x => Complex.exp (f x)) x = Complex.exp (f x) * deriv f x :=
113+
hc.hasDerivAt.cexp.deriv
114+
#align deriv_cexp deriv_cexp
115+
116+
end
117+
118+
section
119+
120+
variable {𝕜 : Type _} [NontriviallyNormedField 𝕜] [NormedAlgebra 𝕜 ℂ] {E : Type _}
121+
[NormedAddCommGroup E] [NormedSpace 𝕜 E] {f : E → ℂ} {f' : E →L[𝕜] ℂ} {x : E} {s : Set E}
122+
123+
theorem HasStrictFDerivAt.cexp (hf : HasStrictFDerivAt f f' x) :
124+
HasStrictFDerivAt (fun x => Complex.exp (f x)) (Complex.exp (f x) • f') x :=
125+
(Complex.hasStrictDerivAt_exp (f x)).comp_hasStrictFDerivAt x hf
126+
#align has_strict_fderiv_at.cexp HasStrictFDerivAt.cexp
127+
128+
theorem HasFDerivWithinAt.cexp (hf : HasFDerivWithinAt f f' s x) :
129+
HasFDerivWithinAt (fun x => Complex.exp (f x)) (Complex.exp (f x) • f') s x :=
130+
(Complex.hasDerivAt_exp (f x)).comp_hasFDerivWithinAt x hf
131+
#align has_fderiv_within_at.cexp HasFDerivWithinAt.cexp
132+
133+
theorem HasFDerivAt.cexp (hf : HasFDerivAt f f' x) :
134+
HasFDerivAt (fun x => Complex.exp (f x)) (Complex.exp (f x) • f') x :=
135+
hasFDerivWithinAt_univ.1 <| hf.hasFDerivWithinAt.cexp
136+
#align has_fderiv_at.cexp HasFDerivAt.cexp
137+
138+
theorem DifferentiableWithinAt.cexp (hf : DifferentiableWithinAt 𝕜 f s x) :
139+
DifferentiableWithinAt 𝕜 (fun x => Complex.exp (f x)) s x :=
140+
hf.hasFDerivWithinAt.cexp.differentiableWithinAt
141+
#align differentiable_within_at.cexp DifferentiableWithinAt.cexp
142+
143+
@[simp]
144+
theorem DifferentiableAt.cexp (hc : DifferentiableAt 𝕜 f x) :
145+
DifferentiableAt 𝕜 (fun x => Complex.exp (f x)) x :=
146+
hc.hasFDerivAt.cexp.differentiableAt
147+
#align differentiable_at.cexp DifferentiableAt.cexp
148+
149+
theorem DifferentiableOn.cexp (hc : DifferentiableOn 𝕜 f s) :
150+
DifferentiableOn 𝕜 (fun x => Complex.exp (f x)) s := fun x h => (hc x h).cexp
151+
#align differentiable_on.cexp DifferentiableOn.cexp
152+
153+
@[simp]
154+
theorem Differentiable.cexp (hc : Differentiable 𝕜 f) :
155+
Differentiable 𝕜 fun x => Complex.exp (f x) := fun x => (hc x).cexp
156+
#align differentiable.cexp Differentiable.cexp
157+
158+
theorem ContDiff.cexp {n} (h : ContDiff 𝕜 n f) : ContDiff 𝕜 n fun x => Complex.exp (f x) :=
159+
Complex.contDiff_exp.comp h
160+
#align cont_diff.cexp ContDiff.cexp
161+
162+
theorem ContDiffAt.cexp {n} (hf : ContDiffAt 𝕜 n f x) :
163+
ContDiffAt 𝕜 n (fun x => Complex.exp (f x)) x :=
164+
Complex.contDiff_exp.contDiffAt.comp x hf
165+
#align cont_diff_at.cexp ContDiffAt.cexp
166+
167+
theorem ContDiffOn.cexp {n} (hf : ContDiffOn 𝕜 n f s) :
168+
ContDiffOn 𝕜 n (fun x => Complex.exp (f x)) s :=
169+
Complex.contDiff_exp.comp_contDiffOn hf
170+
#align cont_diff_on.cexp ContDiffOn.cexp
171+
172+
theorem ContDiffWithinAt.cexp {n} (hf : ContDiffWithinAt 𝕜 n f s x) :
173+
ContDiffWithinAt 𝕜 n (fun x => Complex.exp (f x)) s x :=
174+
Complex.contDiff_exp.contDiffAt.comp_contDiffWithinAt x hf
175+
#align cont_diff_within_at.cexp ContDiffWithinAt.cexp
176+
177+
end
178+
179+
namespace Real
180+
181+
variable {x y z : ℝ}
182+
183+
theorem hasStrictDerivAt_exp (x : ℝ) : HasStrictDerivAt exp (exp x) x :=
184+
(Complex.hasStrictDerivAt_exp x).real_of_complex
185+
#align real.has_strict_deriv_at_exp Real.hasStrictDerivAt_exp
186+
187+
theorem hasDerivAt_exp (x : ℝ) : HasDerivAt exp (exp x) x :=
188+
(Complex.hasDerivAt_exp x).real_of_complex
189+
#align real.has_deriv_at_exp Real.hasDerivAt_exp
190+
191+
theorem contDiff_exp {n} : ContDiff ℝ n exp :=
192+
Complex.contDiff_exp.real_of_complex
193+
#align real.cont_diff_exp Real.contDiff_exp
194+
195+
theorem differentiable_exp : Differentiable ℝ exp := fun x => (hasDerivAt_exp x).differentiableAt
196+
#align real.differentiable_exp Real.differentiable_exp
197+
198+
theorem differentiableAt_exp : DifferentiableAt ℝ exp x :=
199+
differentiable_exp x
200+
#align real.differentiable_at_exp Real.differentiableAt_exp
201+
202+
@[simp]
203+
theorem deriv_exp : deriv exp = exp :=
204+
funext fun x => (hasDerivAt_exp x).deriv
205+
#align real.deriv_exp Real.deriv_exp
206+
207+
@[simp]
208+
theorem iter_deriv_exp : ∀ n : ℕ, (deriv^[n]) exp = exp
209+
| 0 => rfl
210+
| n + 1 => by rw [iterate_succ_apply, deriv_exp, iter_deriv_exp n]
211+
#align real.iter_deriv_exp Real.iter_deriv_exp
212+
213+
end Real
214+
215+
section
216+
217+
/-! Register lemmas for the derivatives of the composition of `Real.exp` with a differentiable
218+
function, for standalone use and use with `simp`. -/
219+
220+
221+
variable {f : ℝ → ℝ} {f' x : ℝ} {s : Set ℝ}
222+
223+
theorem HasStrictDerivAt.exp (hf : HasStrictDerivAt f f' x) :
224+
HasStrictDerivAt (fun x => Real.exp (f x)) (Real.exp (f x) * f') x :=
225+
(Real.hasStrictDerivAt_exp (f x)).comp x hf
226+
#align has_strict_deriv_at.exp HasStrictDerivAt.exp
227+
228+
theorem HasDerivAt.exp (hf : HasDerivAt f f' x) :
229+
HasDerivAt (fun x => Real.exp (f x)) (Real.exp (f x) * f') x :=
230+
(Real.hasDerivAt_exp (f x)).comp x hf
231+
#align has_deriv_at.exp HasDerivAt.exp
232+
233+
theorem HasDerivWithinAt.exp (hf : HasDerivWithinAt f f' s x) :
234+
HasDerivWithinAt (fun x => Real.exp (f x)) (Real.exp (f x) * f') s x :=
235+
(Real.hasDerivAt_exp (f x)).comp_hasDerivWithinAt x hf
236+
#align has_deriv_within_at.exp HasDerivWithinAt.exp
237+
238+
theorem derivWithin_exp (hf : DifferentiableWithinAt ℝ f s x) (hxs : UniqueDiffWithinAt ℝ s x) :
239+
derivWithin (fun x => Real.exp (f x)) s x = Real.exp (f x) * derivWithin f s x :=
240+
hf.hasDerivWithinAt.exp.derivWithin hxs
241+
#align deriv_within_exp derivWithin_exp
242+
243+
@[simp]
244+
theorem deriv_exp (hc : DifferentiableAt ℝ f x) :
245+
deriv (fun x => Real.exp (f x)) x = Real.exp (f x) * deriv f x :=
246+
hc.hasDerivAt.exp.deriv
247+
#align deriv_exp deriv_exp
248+
249+
end
250+
251+
section
252+
253+
/-! Register lemmas for the derivatives of the composition of `Real.exp` with a differentiable
254+
function, for standalone use and use with `simp`. -/
255+
256+
257+
variable {E : Type _} [NormedAddCommGroup E] [NormedSpace ℝ E] {f : E → ℝ} {f' : E →L[ℝ] ℝ} {x : E}
258+
{s : Set E}
259+
260+
theorem ContDiff.exp {n} (hf : ContDiff ℝ n f) : ContDiff ℝ n fun x => Real.exp (f x) :=
261+
Real.contDiff_exp.comp hf
262+
#align cont_diff.exp ContDiff.exp
263+
264+
theorem ContDiffAt.exp {n} (hf : ContDiffAt ℝ n f x) : ContDiffAt ℝ n (fun x => Real.exp (f x)) x :=
265+
Real.contDiff_exp.contDiffAt.comp x hf
266+
#align cont_diff_at.exp ContDiffAt.exp
267+
268+
theorem ContDiffOn.exp {n} (hf : ContDiffOn ℝ n f s) : ContDiffOn ℝ n (fun x => Real.exp (f x)) s :=
269+
Real.contDiff_exp.comp_contDiffOn hf
270+
#align cont_diff_on.exp ContDiffOn.exp
271+
272+
theorem ContDiffWithinAt.exp {n} (hf : ContDiffWithinAt ℝ n f s x) :
273+
ContDiffWithinAt ℝ n (fun x => Real.exp (f x)) s x :=
274+
Real.contDiff_exp.contDiffAt.comp_contDiffWithinAt x hf
275+
#align cont_diff_within_at.exp ContDiffWithinAt.exp
276+
277+
theorem HasFDerivWithinAt.exp (hf : HasFDerivWithinAt f f' s x) :
278+
HasFDerivWithinAt (fun x => Real.exp (f x)) (Real.exp (f x) • f') s x :=
279+
(Real.hasDerivAt_exp (f x)).comp_hasFDerivWithinAt x hf
280+
#align has_fderiv_within_at.exp HasFDerivWithinAt.exp
281+
282+
theorem HasFDerivAt.exp (hf : HasFDerivAt f f' x) :
283+
HasFDerivAt (fun x => Real.exp (f x)) (Real.exp (f x) • f') x :=
284+
(Real.hasDerivAt_exp (f x)).comp_hasFDerivAt x hf
285+
#align has_fderiv_at.exp HasFDerivAt.exp
286+
287+
theorem HasStrictFDerivAt.exp (hf : HasStrictFDerivAt f f' x) :
288+
HasStrictFDerivAt (fun x => Real.exp (f x)) (Real.exp (f x) • f') x :=
289+
(Real.hasStrictDerivAt_exp (f x)).comp_hasStrictFDerivAt x hf
290+
#align has_strict_fderiv_at.exp HasStrictFDerivAt.exp
291+
292+
theorem DifferentiableWithinAt.exp (hf : DifferentiableWithinAt ℝ f s x) :
293+
DifferentiableWithinAt ℝ (fun x => Real.exp (f x)) s x :=
294+
hf.hasFDerivWithinAt.exp.differentiableWithinAt
295+
#align differentiable_within_at.exp DifferentiableWithinAt.exp
296+
297+
@[simp]
298+
theorem DifferentiableAt.exp (hc : DifferentiableAt ℝ f x) :
299+
DifferentiableAt ℝ (fun x => Real.exp (f x)) x :=
300+
hc.hasFDerivAt.exp.differentiableAt
301+
#align differentiable_at.exp DifferentiableAt.exp
302+
303+
theorem DifferentiableOn.exp (hc : DifferentiableOn ℝ f s) :
304+
DifferentiableOn ℝ (fun x => Real.exp (f x)) s := fun x h => (hc x h).exp
305+
#align differentiable_on.exp DifferentiableOn.exp
306+
307+
@[simp]
308+
theorem Differentiable.exp (hc : Differentiable ℝ f) : Differentiable ℝ fun x => Real.exp (f x) :=
309+
fun x => (hc x).exp
310+
#align differentiable.exp Differentiable.exp
311+
312+
theorem fderivWithin_exp (hf : DifferentiableWithinAt ℝ f s x) (hxs : UniqueDiffWithinAt ℝ s x) :
313+
fderivWithin ℝ (fun x => Real.exp (f x)) s x = Real.exp (f x) • fderivWithin ℝ f s x :=
314+
hf.hasFDerivWithinAt.exp.fderivWithin hxs
315+
#align fderiv_within_exp fderivWithin_exp
316+
317+
@[simp]
318+
theorem fderiv_exp (hc : DifferentiableAt ℝ f x) :
319+
fderiv ℝ (fun x => Real.exp (f x)) x = Real.exp (f x) • fderiv ℝ f x :=
320+
hc.hasFDerivAt.exp.fderiv
321+
#align fderiv_exp fderiv_exp
322+
323+
end

0 commit comments

Comments
 (0)