-
Notifications
You must be signed in to change notification settings - Fork 257
/
Mul.lean
454 lines (355 loc) Β· 20.6 KB
/
Mul.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
/-
Copyright (c) 2019 Gabriel Ebner. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Gabriel Ebner, Anatole Dedecker, Yury Kudryashov
-/
import Mathlib.Analysis.Calculus.Deriv.Basic
import Mathlib.Analysis.Calculus.FDeriv.Mul
import Mathlib.Analysis.Calculus.FDeriv.Add
#align_import analysis.calculus.deriv.mul from "leanprover-community/mathlib"@"3bce8d800a6f2b8f63fe1e588fd76a9ff4adcebe"
/-!
# Derivative of `f x * g x`
In this file we prove formulas for `(f x * g x)'` and `(f x β’ g x)'`.
For a more detailed overview of one-dimensional derivatives in mathlib, see the module docstring of
`Analysis/Calculus/Deriv/Basic`.
## Keywords
derivative, multiplication
-/
universe u v w
noncomputable section
open scoped Classical Topology BigOperators Filter ENNReal
open Filter Asymptotics Set
open ContinuousLinearMap (smulRight smulRight_one_eq_iff)
variable {π : Type u} [NontriviallyNormedField π]
variable {F : Type v} [NormedAddCommGroup F] [NormedSpace π F]
variable {E : Type w} [NormedAddCommGroup E] [NormedSpace π E]
variable {f fβ fβ g : π β F}
variable {f' fβ' fβ' g' : F}
variable {x : π}
variable {s t : Set π}
variable {L Lβ Lβ : Filter π}
section SMul
/-! ### Derivative of the multiplication of a scalar function and a vector function -/
variable {π' : Type*} [NontriviallyNormedField π'] [NormedAlgebra π π'] [NormedSpace π' F]
[IsScalarTower π π' F] {c : π β π'} {c' : π'}
theorem HasDerivWithinAt.smul (hc : HasDerivWithinAt c c' s x) (hf : HasDerivWithinAt f f' s x) :
HasDerivWithinAt (fun y => c y β’ f y) (c x β’ f' + c' β’ f x) s x := by
simpa using (HasFDerivWithinAt.smul hc hf).hasDerivWithinAt
#align has_deriv_within_at.smul HasDerivWithinAt.smul
theorem HasDerivAt.smul (hc : HasDerivAt c c' x) (hf : HasDerivAt f f' x) :
HasDerivAt (fun y => c y β’ f y) (c x β’ f' + c' β’ f x) x := by
rw [β hasDerivWithinAt_univ] at *
exact hc.smul hf
#align has_deriv_at.smul HasDerivAt.smul
nonrec theorem HasStrictDerivAt.smul (hc : HasStrictDerivAt c c' x) (hf : HasStrictDerivAt f f' x) :
HasStrictDerivAt (fun y => c y β’ f y) (c x β’ f' + c' β’ f x) x := by
simpa using (hc.smul hf).hasStrictDerivAt
#align has_strict_deriv_at.smul HasStrictDerivAt.smul
theorem derivWithin_smul (hxs : UniqueDiffWithinAt π s x) (hc : DifferentiableWithinAt π c s x)
(hf : DifferentiableWithinAt π f s x) :
derivWithin (fun y => c y β’ f y) s x = c x β’ derivWithin f s x + derivWithin c s x β’ f x :=
(hc.hasDerivWithinAt.smul hf.hasDerivWithinAt).derivWithin hxs
#align deriv_within_smul derivWithin_smul
theorem deriv_smul (hc : DifferentiableAt π c x) (hf : DifferentiableAt π f x) :
deriv (fun y => c y β’ f y) x = c x β’ deriv f x + deriv c x β’ f x :=
(hc.hasDerivAt.smul hf.hasDerivAt).deriv
#align deriv_smul deriv_smul
theorem HasStrictDerivAt.smul_const (hc : HasStrictDerivAt c c' x) (f : F) :
HasStrictDerivAt (fun y => c y β’ f) (c' β’ f) x := by
have := hc.smul (hasStrictDerivAt_const x f)
rwa [smul_zero, zero_add] at this
#align has_strict_deriv_at.smul_const HasStrictDerivAt.smul_const
theorem HasDerivWithinAt.smul_const (hc : HasDerivWithinAt c c' s x) (f : F) :
HasDerivWithinAt (fun y => c y β’ f) (c' β’ f) s x := by
have := hc.smul (hasDerivWithinAt_const x s f)
rwa [smul_zero, zero_add] at this
#align has_deriv_within_at.smul_const HasDerivWithinAt.smul_const
theorem HasDerivAt.smul_const (hc : HasDerivAt c c' x) (f : F) :
HasDerivAt (fun y => c y β’ f) (c' β’ f) x := by
rw [β hasDerivWithinAt_univ] at *
exact hc.smul_const f
#align has_deriv_at.smul_const HasDerivAt.smul_const
theorem derivWithin_smul_const (hxs : UniqueDiffWithinAt π s x)
(hc : DifferentiableWithinAt π c s x) (f : F) :
derivWithin (fun y => c y β’ f) s x = derivWithin c s x β’ f :=
(hc.hasDerivWithinAt.smul_const f).derivWithin hxs
#align deriv_within_smul_const derivWithin_smul_const
theorem deriv_smul_const (hc : DifferentiableAt π c x) (f : F) :
deriv (fun y => c y β’ f) x = deriv c x β’ f :=
(hc.hasDerivAt.smul_const f).deriv
#align deriv_smul_const deriv_smul_const
end SMul
section ConstSMul
variable {R : Type*} [Semiring R] [Module R F] [SMulCommClass π R F] [ContinuousConstSMul R F]
nonrec theorem HasStrictDerivAt.const_smul (c : R) (hf : HasStrictDerivAt f f' x) :
HasStrictDerivAt (fun y => c β’ f y) (c β’ f') x := by
simpa using (hf.const_smul c).hasStrictDerivAt
#align has_strict_deriv_at.const_smul HasStrictDerivAt.const_smul
nonrec theorem HasDerivAtFilter.const_smul (c : R) (hf : HasDerivAtFilter f f' x L) :
HasDerivAtFilter (fun y => c β’ f y) (c β’ f') x L := by
simpa using (hf.const_smul c).hasDerivAtFilter
#align has_deriv_at_filter.const_smul HasDerivAtFilter.const_smul
nonrec theorem HasDerivWithinAt.const_smul (c : R) (hf : HasDerivWithinAt f f' s x) :
HasDerivWithinAt (fun y => c β’ f y) (c β’ f') s x :=
hf.const_smul c
#align has_deriv_within_at.const_smul HasDerivWithinAt.const_smul
nonrec theorem HasDerivAt.const_smul (c : R) (hf : HasDerivAt f f' x) :
HasDerivAt (fun y => c β’ f y) (c β’ f') x :=
hf.const_smul c
#align has_deriv_at.const_smul HasDerivAt.const_smul
theorem derivWithin_const_smul (hxs : UniqueDiffWithinAt π s x) (c : R)
(hf : DifferentiableWithinAt π f s x) :
derivWithin (fun y => c β’ f y) s x = c β’ derivWithin f s x :=
(hf.hasDerivWithinAt.const_smul c).derivWithin hxs
#align deriv_within_const_smul derivWithin_const_smul
theorem deriv_const_smul (c : R) (hf : DifferentiableAt π f x) :
deriv (fun y => c β’ f y) x = c β’ deriv f x :=
(hf.hasDerivAt.const_smul c).deriv
#align deriv_const_smul deriv_const_smul
/-- A variant of `deriv_const_smul` without differentiability assumption when the scalar
multiplication is by field elements. -/
lemma deriv_const_smul' {f : π β F} {x : π} {R : Type*} [Field R] [Module R F] [SMulCommClass π R F]
[ContinuousConstSMul R F] (c : R) :
deriv (fun y β¦ c β’ f y) x = c β’ deriv f x := by
by_cases hf : DifferentiableAt π f x
Β· exact deriv_const_smul c hf
Β· rcases eq_or_ne c 0 with rfl | hc
Β· simp only [zero_smul, deriv_const']
Β· have H : Β¬DifferentiableAt π (fun y β¦ c β’ f y) x := by
contrapose! hf
change DifferentiableAt π (fun y β¦ f y) x
conv => enter [2, y]; rw [β inv_smul_smulβ hc (f y)]
exact DifferentiableAt.const_smul hf cβ»ΒΉ
rw [deriv_zero_of_not_differentiableAt hf, deriv_zero_of_not_differentiableAt H, smul_zero]
end ConstSMul
section Mul
/-! ### Derivative of the multiplication of two functions -/
variable {π' πΈ : Type*} [NormedField π'] [NormedRing πΈ] [NormedAlgebra π π'] [NormedAlgebra π πΈ]
{c d : π β πΈ} {c' d' : πΈ} {u v : π β π'}
theorem HasDerivWithinAt.mul (hc : HasDerivWithinAt c c' s x) (hd : HasDerivWithinAt d d' s x) :
HasDerivWithinAt (fun y => c y * d y) (c' * d x + c x * d') s x := by
have := (HasFDerivWithinAt.mul' hc hd).hasDerivWithinAt
rwa [ContinuousLinearMap.add_apply, ContinuousLinearMap.smul_apply,
ContinuousLinearMap.smulRight_apply, ContinuousLinearMap.smulRight_apply,
ContinuousLinearMap.smulRight_apply, ContinuousLinearMap.one_apply, one_smul, one_smul,
add_comm] at this
#align has_deriv_within_at.mul HasDerivWithinAt.mul
theorem HasDerivAt.mul (hc : HasDerivAt c c' x) (hd : HasDerivAt d d' x) :
HasDerivAt (fun y => c y * d y) (c' * d x + c x * d') x := by
rw [β hasDerivWithinAt_univ] at *
exact hc.mul hd
#align has_deriv_at.mul HasDerivAt.mul
theorem HasStrictDerivAt.mul (hc : HasStrictDerivAt c c' x) (hd : HasStrictDerivAt d d' x) :
HasStrictDerivAt (fun y => c y * d y) (c' * d x + c x * d') x := by
have := (HasStrictFDerivAt.mul' hc hd).hasStrictDerivAt
rwa [ContinuousLinearMap.add_apply, ContinuousLinearMap.smul_apply,
ContinuousLinearMap.smulRight_apply, ContinuousLinearMap.smulRight_apply,
ContinuousLinearMap.smulRight_apply, ContinuousLinearMap.one_apply, one_smul, one_smul,
add_comm] at this
#align has_strict_deriv_at.mul HasStrictDerivAt.mul
theorem derivWithin_mul (hxs : UniqueDiffWithinAt π s x) (hc : DifferentiableWithinAt π c s x)
(hd : DifferentiableWithinAt π d s x) :
derivWithin (fun y => c y * d y) s x = derivWithin c s x * d x + c x * derivWithin d s x :=
(hc.hasDerivWithinAt.mul hd.hasDerivWithinAt).derivWithin hxs
#align deriv_within_mul derivWithin_mul
@[simp]
theorem deriv_mul (hc : DifferentiableAt π c x) (hd : DifferentiableAt π d x) :
deriv (fun y => c y * d y) x = deriv c x * d x + c x * deriv d x :=
(hc.hasDerivAt.mul hd.hasDerivAt).deriv
#align deriv_mul deriv_mul
theorem HasDerivWithinAt.mul_const (hc : HasDerivWithinAt c c' s x) (d : πΈ) :
HasDerivWithinAt (fun y => c y * d) (c' * d) s x := by
convert hc.mul (hasDerivWithinAt_const x s d) using 1
rw [mul_zero, add_zero]
#align has_deriv_within_at.mul_const HasDerivWithinAt.mul_const
theorem HasDerivAt.mul_const (hc : HasDerivAt c c' x) (d : πΈ) :
HasDerivAt (fun y => c y * d) (c' * d) x := by
rw [β hasDerivWithinAt_univ] at *
exact hc.mul_const d
#align has_deriv_at.mul_const HasDerivAt.mul_const
theorem hasDerivAt_mul_const (c : π) : HasDerivAt (fun x => x * c) c x := by
simpa only [one_mul] using (hasDerivAt_id' x).mul_const c
#align has_deriv_at_mul_const hasDerivAt_mul_const
theorem HasStrictDerivAt.mul_const (hc : HasStrictDerivAt c c' x) (d : πΈ) :
HasStrictDerivAt (fun y => c y * d) (c' * d) x := by
convert hc.mul (hasStrictDerivAt_const x d) using 1
rw [mul_zero, add_zero]
#align has_strict_deriv_at.mul_const HasStrictDerivAt.mul_const
theorem derivWithin_mul_const (hxs : UniqueDiffWithinAt π s x) (hc : DifferentiableWithinAt π c s x)
(d : πΈ) : derivWithin (fun y => c y * d) s x = derivWithin c s x * d :=
(hc.hasDerivWithinAt.mul_const d).derivWithin hxs
#align deriv_within_mul_const derivWithin_mul_const
theorem deriv_mul_const (hc : DifferentiableAt π c x) (d : πΈ) :
deriv (fun y => c y * d) x = deriv c x * d :=
(hc.hasDerivAt.mul_const d).deriv
#align deriv_mul_const deriv_mul_const
theorem deriv_mul_const_field (v : π') : deriv (fun y => u y * v) x = deriv u x * v := by
by_cases hu : DifferentiableAt π u x
Β· exact deriv_mul_const hu v
Β· rw [deriv_zero_of_not_differentiableAt hu, zero_mul]
rcases eq_or_ne v 0 with (rfl | hd)
Β· simp only [mul_zero, deriv_const]
Β· refine' deriv_zero_of_not_differentiableAt (mt (fun H => _) hu)
simpa only [mul_inv_cancel_rightβ hd] using H.mul_const vβ»ΒΉ
#align deriv_mul_const_field deriv_mul_const_field
@[simp]
theorem deriv_mul_const_field' (v : π') : (deriv fun x => u x * v) = fun x => deriv u x * v :=
funext fun _ => deriv_mul_const_field v
#align deriv_mul_const_field' deriv_mul_const_field'
theorem HasDerivWithinAt.const_mul (c : πΈ) (hd : HasDerivWithinAt d d' s x) :
HasDerivWithinAt (fun y => c * d y) (c * d') s x := by
convert (hasDerivWithinAt_const x s c).mul hd using 1
rw [zero_mul, zero_add]
#align has_deriv_within_at.const_mul HasDerivWithinAt.const_mul
theorem HasDerivAt.const_mul (c : πΈ) (hd : HasDerivAt d d' x) :
HasDerivAt (fun y => c * d y) (c * d') x := by
rw [β hasDerivWithinAt_univ] at *
exact hd.const_mul c
#align has_deriv_at.const_mul HasDerivAt.const_mul
theorem HasStrictDerivAt.const_mul (c : πΈ) (hd : HasStrictDerivAt d d' x) :
HasStrictDerivAt (fun y => c * d y) (c * d') x := by
convert (hasStrictDerivAt_const _ _).mul hd using 1
rw [zero_mul, zero_add]
#align has_strict_deriv_at.const_mul HasStrictDerivAt.const_mul
theorem derivWithin_const_mul (hxs : UniqueDiffWithinAt π s x) (c : πΈ)
(hd : DifferentiableWithinAt π d s x) :
derivWithin (fun y => c * d y) s x = c * derivWithin d s x :=
(hd.hasDerivWithinAt.const_mul c).derivWithin hxs
#align deriv_within_const_mul derivWithin_const_mul
theorem deriv_const_mul (c : πΈ) (hd : DifferentiableAt π d x) :
deriv (fun y => c * d y) x = c * deriv d x :=
(hd.hasDerivAt.const_mul c).deriv
#align deriv_const_mul deriv_const_mul
theorem deriv_const_mul_field (u : π') : deriv (fun y => u * v y) x = u * deriv v x := by
simp only [mul_comm u, deriv_mul_const_field]
#align deriv_const_mul_field deriv_const_mul_field
@[simp]
theorem deriv_const_mul_field' (u : π') : (deriv fun x => u * v x) = fun x => u * deriv v x :=
funext fun _ => deriv_const_mul_field u
#align deriv_const_mul_field' deriv_const_mul_field'
end Mul
section Prod
variable {ΞΉ : Type*} [DecidableEq ΞΉ] {πΈ' : Type*} [NormedCommRing πΈ'] [NormedAlgebra π πΈ']
{u : Finset ΞΉ} {f : ΞΉ β π β πΈ'} {f' : ΞΉ β πΈ'}
theorem HasDerivAt.finset_prod (hf : β i β u, HasDerivAt (f i) (f' i) x) :
HasDerivAt (β i in u, f i Β·) (β i in u, (β j in u.erase i, f j x) β’ f' i) x := by
simpa [ContinuousLinearMap.sum_apply, ContinuousLinearMap.smul_apply] using
(HasFDerivAt.finset_prod (fun i hi β¦ (hf i hi).hasFDerivAt)).hasDerivAt
theorem HasDerivWithinAt.finset_prod (hf : β i β u, HasDerivWithinAt (f i) (f' i) s x) :
HasDerivWithinAt (β i in u, f i Β·) (β i in u, (β j in u.erase i, f j x) β’ f' i) s x := by
simpa [ContinuousLinearMap.sum_apply, ContinuousLinearMap.smul_apply] using
(HasFDerivWithinAt.finset_prod (fun i hi β¦ (hf i hi).hasFDerivWithinAt)).hasDerivWithinAt
theorem HasStrictDerivAt.finset_prod (hf : β i β u, HasStrictDerivAt (f i) (f' i) x) :
HasStrictDerivAt (β i in u, f i Β·) (β i in u, (β j in u.erase i, f j x) β’ f' i) x := by
simpa [ContinuousLinearMap.sum_apply, ContinuousLinearMap.smul_apply] using
(HasStrictFDerivAt.finset_prod (fun i hi β¦ (hf i hi).hasStrictFDerivAt)).hasStrictDerivAt
theorem deriv_finset_prod (hf : β i β u, DifferentiableAt π (f i) x) :
deriv (β i in u, f i Β·) x = β i in u, (β j in u.erase i, f j x) β’ deriv (f i) x :=
(HasDerivAt.finset_prod fun i hi β¦ (hf i hi).hasDerivAt).deriv
theorem derivWithin_finset_prod (hxs : UniqueDiffWithinAt π s x)
(hf : β i β u, DifferentiableWithinAt π (f i) s x) :
derivWithin (β i in u, f i Β·) s x =
β i in u, (β j in u.erase i, f j x) β’ derivWithin (f i) s x :=
(HasDerivWithinAt.finset_prod fun i hi β¦ (hf i hi).hasDerivWithinAt).derivWithin hxs
end Prod
section Div
variable {π' : Type*} [NontriviallyNormedField π'] [NormedAlgebra π π'] {c d : π β π'} {c' d' : π'}
theorem HasDerivAt.div_const (hc : HasDerivAt c c' x) (d : π') :
HasDerivAt (fun x => c x / d) (c' / d) x := by
simpa only [div_eq_mul_inv] using hc.mul_const dβ»ΒΉ
#align has_deriv_at.div_const HasDerivAt.div_const
theorem HasDerivWithinAt.div_const (hc : HasDerivWithinAt c c' s x) (d : π') :
HasDerivWithinAt (fun x => c x / d) (c' / d) s x := by
simpa only [div_eq_mul_inv] using hc.mul_const dβ»ΒΉ
#align has_deriv_within_at.div_const HasDerivWithinAt.div_const
theorem HasStrictDerivAt.div_const (hc : HasStrictDerivAt c c' x) (d : π') :
HasStrictDerivAt (fun x => c x / d) (c' / d) x := by
simpa only [div_eq_mul_inv] using hc.mul_const dβ»ΒΉ
#align has_strict_deriv_at.div_const HasStrictDerivAt.div_const
theorem DifferentiableWithinAt.div_const (hc : DifferentiableWithinAt π c s x) (d : π') :
DifferentiableWithinAt π (fun x => c x / d) s x :=
(hc.hasDerivWithinAt.div_const _).differentiableWithinAt
#align differentiable_within_at.div_const DifferentiableWithinAt.div_const
@[simp]
theorem DifferentiableAt.div_const (hc : DifferentiableAt π c x) (d : π') :
DifferentiableAt π (fun x => c x / d) x :=
(hc.hasDerivAt.div_const _).differentiableAt
#align differentiable_at.div_const DifferentiableAt.div_const
theorem DifferentiableOn.div_const (hc : DifferentiableOn π c s) (d : π') :
DifferentiableOn π (fun x => c x / d) s := fun x hx => (hc x hx).div_const d
#align differentiable_on.div_const DifferentiableOn.div_const
@[simp]
theorem Differentiable.div_const (hc : Differentiable π c) (d : π') :
Differentiable π fun x => c x / d := fun x => (hc x).div_const d
#align differentiable.div_const Differentiable.div_const
theorem derivWithin_div_const (hc : DifferentiableWithinAt π c s x) (d : π')
(hxs : UniqueDiffWithinAt π s x) : derivWithin (fun x => c x / d) s x = derivWithin c s x / d :=
by simp [div_eq_inv_mul, derivWithin_const_mul, hc, hxs]
#align deriv_within_div_const derivWithin_div_const
@[simp]
theorem deriv_div_const (d : π') : deriv (fun x => c x / d) x = deriv c x / d := by
simp only [div_eq_mul_inv, deriv_mul_const_field]
#align deriv_div_const deriv_div_const
end Div
section CLMCompApply
/-! ### Derivative of the pointwise composition/application of continuous linear maps -/
open ContinuousLinearMap
variable {G : Type*} [NormedAddCommGroup G] [NormedSpace π G] {c : π β F βL[π] G} {c' : F βL[π] G}
{d : π β E βL[π] F} {d' : E βL[π] F} {u : π β F} {u' : F}
theorem HasStrictDerivAt.clm_comp (hc : HasStrictDerivAt c c' x) (hd : HasStrictDerivAt d d' x) :
HasStrictDerivAt (fun y => (c y).comp (d y)) (c'.comp (d x) + (c x).comp d') x := by
have := (hc.hasStrictFDerivAt.clm_comp hd.hasStrictFDerivAt).hasStrictDerivAt
rwa [add_apply, comp_apply, comp_apply, smulRight_apply, smulRight_apply, one_apply, one_smul,
one_smul, add_comm] at this
#align has_strict_deriv_at.clm_comp HasStrictDerivAt.clm_comp
theorem HasDerivWithinAt.clm_comp (hc : HasDerivWithinAt c c' s x)
(hd : HasDerivWithinAt d d' s x) :
HasDerivWithinAt (fun y => (c y).comp (d y)) (c'.comp (d x) + (c x).comp d') s x := by
have := (hc.hasFDerivWithinAt.clm_comp hd.hasFDerivWithinAt).hasDerivWithinAt
rwa [add_apply, comp_apply, comp_apply, smulRight_apply, smulRight_apply, one_apply, one_smul,
one_smul, add_comm] at this
#align has_deriv_within_at.clm_comp HasDerivWithinAt.clm_comp
theorem HasDerivAt.clm_comp (hc : HasDerivAt c c' x) (hd : HasDerivAt d d' x) :
HasDerivAt (fun y => (c y).comp (d y)) (c'.comp (d x) + (c x).comp d') x := by
rw [β hasDerivWithinAt_univ] at *
exact hc.clm_comp hd
#align has_deriv_at.clm_comp HasDerivAt.clm_comp
theorem derivWithin_clm_comp (hc : DifferentiableWithinAt π c s x)
(hd : DifferentiableWithinAt π d s x) (hxs : UniqueDiffWithinAt π s x) :
derivWithin (fun y => (c y).comp (d y)) s x =
(derivWithin c s x).comp (d x) + (c x).comp (derivWithin d s x) :=
(hc.hasDerivWithinAt.clm_comp hd.hasDerivWithinAt).derivWithin hxs
#align deriv_within_clm_comp derivWithin_clm_comp
theorem deriv_clm_comp (hc : DifferentiableAt π c x) (hd : DifferentiableAt π d x) :
deriv (fun y => (c y).comp (d y)) x = (deriv c x).comp (d x) + (c x).comp (deriv d x) :=
(hc.hasDerivAt.clm_comp hd.hasDerivAt).deriv
#align deriv_clm_comp deriv_clm_comp
theorem HasStrictDerivAt.clm_apply (hc : HasStrictDerivAt c c' x) (hu : HasStrictDerivAt u u' x) :
HasStrictDerivAt (fun y => (c y) (u y)) (c' (u x) + c x u') x := by
have := (hc.hasStrictFDerivAt.clm_apply hu.hasStrictFDerivAt).hasStrictDerivAt
rwa [add_apply, comp_apply, flip_apply, smulRight_apply, smulRight_apply, one_apply, one_smul,
one_smul, add_comm] at this
#align has_strict_deriv_at.clm_apply HasStrictDerivAt.clm_apply
theorem HasDerivWithinAt.clm_apply (hc : HasDerivWithinAt c c' s x)
(hu : HasDerivWithinAt u u' s x) :
HasDerivWithinAt (fun y => (c y) (u y)) (c' (u x) + c x u') s x := by
have := (hc.hasFDerivWithinAt.clm_apply hu.hasFDerivWithinAt).hasDerivWithinAt
rwa [add_apply, comp_apply, flip_apply, smulRight_apply, smulRight_apply, one_apply, one_smul,
one_smul, add_comm] at this
#align has_deriv_within_at.clm_apply HasDerivWithinAt.clm_apply
theorem HasDerivAt.clm_apply (hc : HasDerivAt c c' x) (hu : HasDerivAt u u' x) :
HasDerivAt (fun y => (c y) (u y)) (c' (u x) + c x u') x := by
have := (hc.hasFDerivAt.clm_apply hu.hasFDerivAt).hasDerivAt
rwa [add_apply, comp_apply, flip_apply, smulRight_apply, smulRight_apply, one_apply, one_smul,
one_smul, add_comm] at this
#align has_deriv_at.clm_apply HasDerivAt.clm_apply
theorem derivWithin_clm_apply (hxs : UniqueDiffWithinAt π s x) (hc : DifferentiableWithinAt π c s x)
(hu : DifferentiableWithinAt π u s x) :
derivWithin (fun y => (c y) (u y)) s x = derivWithin c s x (u x) + c x (derivWithin u s x) :=
(hc.hasDerivWithinAt.clm_apply hu.hasDerivWithinAt).derivWithin hxs
#align deriv_within_clm_apply derivWithin_clm_apply
theorem deriv_clm_apply (hc : DifferentiableAt π c x) (hu : DifferentiableAt π u x) :
deriv (fun y => (c y) (u y)) x = deriv c x (u x) + c x (deriv u x) :=
(hc.hasDerivAt.clm_apply hu.hasDerivAt).deriv
#align deriv_clm_apply deriv_clm_apply
end CLMCompApply