Skip to content

Commit 40b5578

Browse files
committed
feat: expand API around manifold derivatives (#18850)
Notably, prove that basic functions are differentiable in the manifold sense, and compute their derivatives.
1 parent 159918f commit 40b5578

File tree

3 files changed

+303
-5
lines changed

3 files changed

+303
-5
lines changed

Mathlib/Geometry/Manifold/Algebra/Monoid.lean

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Nicolò Cavalleri
55
-/
66
import Mathlib.Geometry.Manifold.ContMDiffMap
7+
import Mathlib.Geometry.Manifold.MFDeriv.Basic
78

89
/-!
910
# Smooth monoid
@@ -132,6 +133,28 @@ theorem smooth_mul_left {a : G} : Smooth I I fun b : G => a * b :=
132133
theorem smooth_mul_right {a : G} : Smooth I I fun b : G => b * a :=
133134
smooth_id.mul smooth_const
134135

136+
theorem contMDiff_mul_left {a : G} : ContMDiff I I n (a * ·) := smooth_mul_left.contMDiff
137+
138+
theorem contMDiffAt_mul_left {a b : G} : ContMDiffAt I I n (a * ·) b :=
139+
contMDiff_mul_left.contMDiffAt
140+
141+
theorem mdifferentiable_mul_left {a : G} : MDifferentiable I I (a * ·) :=
142+
contMDiff_mul_left.mdifferentiable le_rfl
143+
144+
theorem mdifferentiableAt_mul_left {a b : G} : MDifferentiableAt I I (a * ·) b :=
145+
contMDiffAt_mul_left.mdifferentiableAt le_rfl
146+
147+
theorem contMDiff_mul_right {a : G} : ContMDiff I I n (· * a) := smooth_mul_right.contMDiff
148+
149+
theorem contMDiffAt_mul_right {a b : G} : ContMDiffAt I I n (· * a) b :=
150+
contMDiff_mul_right.contMDiffAt
151+
152+
theorem mdifferentiable_mul_right {a : G} : MDifferentiable I I (· * a) :=
153+
contMDiff_mul_right.mdifferentiable le_rfl
154+
155+
theorem mdifferentiableAt_mul_right {a b : G} : MDifferentiableAt I I (· * a) b :=
156+
contMDiffAt_mul_right.mdifferentiableAt le_rfl
157+
135158
end
136159

137160
variable (I) (g h : G)

Mathlib/Geometry/Manifold/MFDeriv/Atlas.lean

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,4 +257,96 @@ theorem mdifferentiableOn_extChartAt_symm :
257257
intro y hy
258258
exact (mdifferentiableWithinAt_extChartAt_symm hy).mono (extChartAt_target_subset_range x)
259259

260+
/-- The composition of the derivative of `extChartAt` with the derivative of the inverse of
261+
`extChartAt` gives the identity.
262+
Version where the basepoint belongs to `(extChartAt I x).target`. -/
263+
lemma mfderiv_extChartAt_comp_mfderivWithin_extChartAt_symm {x : M}
264+
{y : E} (hy : y ∈ (extChartAt I x).target) :
265+
(mfderiv I 𝓘(𝕜, E) (extChartAt I x) ((extChartAt I x).symm y)) ∘L
266+
(mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) y) = ContinuousLinearMap.id _ _ := by
267+
have U : UniqueMDiffWithinAt 𝓘(𝕜, E) (range ↑I) y := by
268+
apply I.uniqueMDiffOn
269+
exact extChartAt_target_subset_range x hy
270+
have h'y : (extChartAt I x).symm y ∈ (extChartAt I x).source := (extChartAt I x).map_target hy
271+
have h''y : (extChartAt I x).symm y ∈ (chartAt H x).source := by
272+
rwa [← extChartAt_source (I := I)]
273+
rw [← mfderiv_comp_mfderivWithin]; rotate_left
274+
· apply mdifferentiableAt_extChartAt h''y
275+
· exact mdifferentiableWithinAt_extChartAt_symm hy
276+
· exact U
277+
rw [← mfderivWithin_id U]
278+
apply Filter.EventuallyEq.mfderivWithin_eq U
279+
· filter_upwards [extChartAt_target_mem_nhdsWithin_of_mem hy] with z hz
280+
simp only [Function.comp_def, PartialEquiv.right_inv (extChartAt I x) hz, id_eq]
281+
· simp only [Function.comp_def, PartialEquiv.right_inv (extChartAt I x) hy, id_eq]
282+
283+
/-- The composition of the derivative of `extChartAt` with the derivative of the inverse of
284+
`extChartAt` gives the identity.
285+
Version where the basepoint belongs to `(extChartAt I x).source`. -/
286+
lemma mfderiv_extChartAt_comp_mfderivWithin_extChartAt_symm' {x : M}
287+
{y : M} (hy : y ∈ (extChartAt I x).source) :
288+
(mfderiv I 𝓘(𝕜, E) (extChartAt I x) y) ∘L
289+
(mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) (extChartAt I x y))
290+
= ContinuousLinearMap.id _ _ := by
291+
have : y = (extChartAt I x).symm (extChartAt I x y) := ((extChartAt I x).left_inv hy).symm
292+
convert mfderiv_extChartAt_comp_mfderivWithin_extChartAt_symm ((extChartAt I x).map_source hy)
293+
294+
/-- The composition of the derivative of the inverse of `extChartAt` with the derivative of
295+
`extChartAt` gives the identity.
296+
Version where the basepoint belongs to `(extChartAt I x).target`. -/
297+
lemma mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt
298+
{y : E} (hy : y ∈ (extChartAt I x).target) :
299+
(mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) y) ∘L
300+
(mfderiv I 𝓘(𝕜, E) (extChartAt I x) ((extChartAt I x).symm y))
301+
= ContinuousLinearMap.id _ _ := by
302+
have h'y : (extChartAt I x).symm y ∈ (extChartAt I x).source := (extChartAt I x).map_target hy
303+
have h''y : (extChartAt I x).symm y ∈ (chartAt H x).source := by
304+
rwa [← extChartAt_source (I := I)]
305+
have U' : UniqueMDiffWithinAt I (extChartAt I x).source ((extChartAt I x).symm y) :=
306+
(isOpen_extChartAt_source x).uniqueMDiffWithinAt h'y
307+
have : mfderiv I 𝓘(𝕜, E) (extChartAt I x) ((extChartAt I x).symm y)
308+
= mfderivWithin I 𝓘(𝕜, E) (extChartAt I x) (extChartAt I x).source
309+
((extChartAt I x).symm y) := by
310+
rw [mfderivWithin_eq_mfderiv U']
311+
exact mdifferentiableAt_extChartAt h''y
312+
rw [this, ← mfderivWithin_comp_of_eq]; rotate_left
313+
· exact mdifferentiableWithinAt_extChartAt_symm hy
314+
· exact (mdifferentiableAt_extChartAt h''y).mdifferentiableWithinAt
315+
· intro z hz
316+
apply extChartAt_target_subset_range x
317+
exact PartialEquiv.map_source (extChartAt I x) hz
318+
· exact U'
319+
· exact PartialEquiv.right_inv (extChartAt I x) hy
320+
rw [← mfderivWithin_id U']
321+
apply Filter.EventuallyEq.mfderivWithin_eq U'
322+
· filter_upwards [extChartAt_source_mem_nhdsWithin' h'y] with z hz
323+
simp only [Function.comp_def, PartialEquiv.left_inv (extChartAt I x) hz, id_eq]
324+
· simp only [Function.comp_def, PartialEquiv.right_inv (extChartAt I x) hy, id_eq]
325+
326+
/-- The composition of the derivative of the inverse of `extChartAt` with the derivative of
327+
`extChartAt` gives the identity.
328+
Version where the basepoint belongs to `(extChartAt I x).source`. -/
329+
lemma mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt'
330+
{y : M} (hy : y ∈ (extChartAt I x).source) :
331+
(mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) (extChartAt I x y)) ∘L
332+
(mfderiv I 𝓘(𝕜, E) (extChartAt I x) y)
333+
= ContinuousLinearMap.id _ _ := by
334+
have : y = (extChartAt I x).symm (extChartAt I x y) := ((extChartAt I x).left_inv hy).symm
335+
convert mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt ((extChartAt I x).map_source hy)
336+
337+
lemma isInvertible_mfderivWithin_extChartAt_symm {y : E} (hy : y ∈ (extChartAt I x).target) :
338+
(mfderivWithin 𝓘(𝕜, E) I (extChartAt I x).symm (range I) y).IsInvertible :=
339+
ContinuousLinearMap.IsInvertible.of_inverse
340+
(mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt hy)
341+
(mfderiv_extChartAt_comp_mfderivWithin_extChartAt_symm hy)
342+
343+
lemma isInvertible_mfderiv_extChartAt {y : M} (hy : y ∈ (extChartAt I x).source) :
344+
(mfderiv I 𝓘(𝕜, E) (extChartAt I x) y).IsInvertible := by
345+
have h'y : extChartAt I x y ∈ (extChartAt I x).target := (extChartAt I x).map_source hy
346+
have Z := ContinuousLinearMap.IsInvertible.of_inverse
347+
(mfderiv_extChartAt_comp_mfderivWithin_extChartAt_symm h'y)
348+
(mfderivWithin_extChartAt_symm_comp_mfderiv_extChartAt h'y)
349+
have : (extChartAt I x).symm ((extChartAt I x) y) = y := (extChartAt I x).left_inv hy
350+
rwa [this] at Z
351+
260352
end extChartAt

Mathlib/Geometry/Manifold/MFDeriv/SpecificFunctions.lean

Lines changed: 188 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,31 @@ section SpecificFunctions
2626

2727
/-! ### Differentiability of specific functions -/
2828

29-
variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E : Type*} [NormedAddCommGroup E]
29+
variable {𝕜 : Type*} [NontriviallyNormedField 𝕜]
30+
-- declare a charted space `M` over the pair `(E, H)`.
31+
{E : Type*} [NormedAddCommGroup E]
3032
[NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H] {I : ModelWithCorners 𝕜 E H} {M : Type*}
31-
[TopologicalSpace M] [ChartedSpace H M] {E' : Type*}
32-
[NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H']
33+
[TopologicalSpace M] [ChartedSpace H M]
34+
-- declare a charted space `M'` over the pair `(E', H')`.
35+
{E' : Type*} [NormedAddCommGroup E'] [NormedSpace 𝕜 E'] {H' : Type*} [TopologicalSpace H']
3336
{I' : ModelWithCorners 𝕜 E' H'} {M' : Type*} [TopologicalSpace M'] [ChartedSpace H' M']
37+
-- declare a charted space `M''` over the pair `(E'', H'')`.
3438
{E'' : Type*} [NormedAddCommGroup E''] [NormedSpace 𝕜 E'']
3539
{H'' : Type*} [TopologicalSpace H''] {I'' : ModelWithCorners 𝕜 E'' H''} {M'' : Type*}
3640
[TopologicalSpace M''] [ChartedSpace H'' M'']
41+
-- declare a charted space `N` over the pair `(F, G)`.
42+
{F : Type*}
43+
[NormedAddCommGroup F] [NormedSpace 𝕜 F] {G : Type*} [TopologicalSpace G]
44+
{J : ModelWithCorners 𝕜 F G} {N : Type*} [TopologicalSpace N] [ChartedSpace G N]
45+
-- declare a charted space `N'` over the pair `(F', G')`.
46+
{F' : Type*}
47+
[NormedAddCommGroup F'] [NormedSpace 𝕜 F'] {G' : Type*} [TopologicalSpace G']
48+
{J' : ModelWithCorners 𝕜 F' G'} {N' : Type*} [TopologicalSpace N'] [ChartedSpace G' N']
49+
-- F₁, F₂, F₃, F₄ are normed spaces
50+
{F₁ : Type*}
51+
[NormedAddCommGroup F₁] [NormedSpace 𝕜 F₁] {F₂ : Type*} [NormedAddCommGroup F₂]
52+
[NormedSpace 𝕜 F₂] {F₃ : Type*} [NormedAddCommGroup F₃] [NormedSpace 𝕜 F₃] {F₄ : Type*}
53+
[NormedAddCommGroup F₄] [NormedSpace 𝕜 F₄]
3754

3855
namespace ContinuousLinearMap
3956

@@ -301,6 +318,128 @@ theorem mfderivWithin_snd {s : Set (M × M')} {x : M × M'}
301318
ContinuousLinearMap.snd 𝕜 (TangentSpace I x.1) (TangentSpace I' x.2) := by
302319
rw [MDifferentiable.mfderivWithin mdifferentiableAt_snd hxs]; exact mfderiv_snd
303320

321+
theorem MDifferentiableWithinAt.fst {f : N → M × M'} {s : Set N} {x : N}
322+
(hf : MDifferentiableWithinAt J (I.prod I') f s x) :
323+
MDifferentiableWithinAt J I (fun x => (f x).1) s x :=
324+
mdifferentiableAt_fst.comp_mdifferentiableWithinAt x hf
325+
326+
theorem MDifferentiableAt.fst {f : N → M × M'} {x : N} (hf : MDifferentiableAt J (I.prod I') f x) :
327+
MDifferentiableAt J I (fun x => (f x).1) x :=
328+
mdifferentiableAt_fst.comp x hf
329+
330+
theorem MDifferentiable.fst {f : N → M × M'} (hf : MDifferentiable J (I.prod I') f) :
331+
MDifferentiable J I fun x => (f x).1 :=
332+
mdifferentiable_fst.comp hf
333+
334+
theorem MDifferentiableWithinAt.snd {f : N → M × M'} {s : Set N} {x : N}
335+
(hf : MDifferentiableWithinAt J (I.prod I') f s x) :
336+
MDifferentiableWithinAt J I' (fun x => (f x).2) s x :=
337+
mdifferentiableAt_snd.comp_mdifferentiableWithinAt x hf
338+
339+
theorem MDifferentiableAt.snd {f : N → M × M'} {x : N} (hf : MDifferentiableAt J (I.prod I') f x) :
340+
MDifferentiableAt J I' (fun x => (f x).2) x :=
341+
mdifferentiableAt_snd.comp x hf
342+
343+
theorem MDifferentiable.snd {f : N → M × M'} (hf : MDifferentiable J (I.prod I') f) :
344+
MDifferentiable J I' fun x => (f x).2 :=
345+
mdifferentiable_snd.comp hf
346+
347+
theorem mdifferentiableWithinAt_prod_iff (f : M → M' × N') :
348+
MDifferentiableWithinAt I (I'.prod J') f s x ↔
349+
MDifferentiableWithinAt I I' (Prod.fst ∘ f) s x
350+
∧ MDifferentiableWithinAt I J' (Prod.snd ∘ f) s x :=
351+
fun h => ⟨h.fst, h.snd⟩, fun h => h.1.prod_mk h.2
352+
353+
theorem mdifferentiableWithinAt_prod_module_iff (f : M → F₁ × F₂) :
354+
MDifferentiableWithinAt I 𝓘(𝕜, F₁ × F₂) f s x ↔
355+
MDifferentiableWithinAt I 𝓘(𝕜, F₁) (Prod.fst ∘ f) s x ∧
356+
MDifferentiableWithinAt I 𝓘(𝕜, F₂) (Prod.snd ∘ f) s x := by
357+
rw [modelWithCornersSelf_prod, ← chartedSpaceSelf_prod]
358+
exact mdifferentiableWithinAt_prod_iff f
359+
360+
theorem mdifferentiableAt_prod_iff (f : M → M' × N') :
361+
MDifferentiableAt I (I'.prod J') f x ↔
362+
MDifferentiableAt I I' (Prod.fst ∘ f) x ∧ MDifferentiableAt I J' (Prod.snd ∘ f) x := by
363+
simp_rw [← mdifferentiableWithinAt_univ]; exact mdifferentiableWithinAt_prod_iff f
364+
365+
theorem mdifferentiableAt_prod_module_iff (f : M → F₁ × F₂) :
366+
MDifferentiableAt I 𝓘(𝕜, F₁ × F₂) f x ↔
367+
MDifferentiableAt I 𝓘(𝕜, F₁) (Prod.fst ∘ f) x
368+
∧ MDifferentiableAt I 𝓘(𝕜, F₂) (Prod.snd ∘ f) x := by
369+
rw [modelWithCornersSelf_prod, ← chartedSpaceSelf_prod]
370+
exact mdifferentiableAt_prod_iff f
371+
372+
theorem mdifferentiableOn_prod_iff (f : M → M' × N') :
373+
MDifferentiableOn I (I'.prod J') f s ↔
374+
MDifferentiableOn I I' (Prod.fst ∘ f) s ∧ MDifferentiableOn I J' (Prod.snd ∘ f) s :=
375+
fun h ↦ ⟨fun x hx ↦ ((mdifferentiableWithinAt_prod_iff f).1 (h x hx)).1,
376+
fun x hx ↦ ((mdifferentiableWithinAt_prod_iff f).1 (h x hx)).2⟩ ,
377+
fun h x hx ↦ (mdifferentiableWithinAt_prod_iff f).2 ⟨h.1 x hx, h.2 x hx⟩⟩
378+
379+
theorem mdifferentiableOn_prod_module_iff (f : M → F₁ × F₂) :
380+
MDifferentiableOn I 𝓘(𝕜, F₁ × F₂) f s ↔
381+
MDifferentiableOn I 𝓘(𝕜, F₁) (Prod.fst ∘ f) s
382+
∧ MDifferentiableOn I 𝓘(𝕜, F₂) (Prod.snd ∘ f) s := by
383+
rw [modelWithCornersSelf_prod, ← chartedSpaceSelf_prod]
384+
exact mdifferentiableOn_prod_iff f
385+
386+
theorem mdifferentiable_prod_iff (f : M → M' × N') :
387+
MDifferentiable I (I'.prod J') f ↔
388+
MDifferentiable I I' (Prod.fst ∘ f) ∧ MDifferentiable I J' (Prod.snd ∘ f) :=
389+
fun h => ⟨h.fst, h.snd⟩, fun h => by convert h.1.prod_mk h.2
390+
391+
theorem mdifferentiable_prod_module_iff (f : M → F₁ × F₂) :
392+
MDifferentiable I 𝓘(𝕜, F₁ × F₂) f ↔
393+
MDifferentiable I 𝓘(𝕜, F₁) (Prod.fst ∘ f) ∧ MDifferentiable I 𝓘(𝕜, F₂) (Prod.snd ∘ f) := by
394+
rw [modelWithCornersSelf_prod, ← chartedSpaceSelf_prod]
395+
exact mdifferentiable_prod_iff f
396+
397+
398+
section prodMap
399+
400+
variable {f : M → M'} {g : N → N'} {r : Set N} {y : N}
401+
402+
/-- The product map of two `C^n` functions within a set at a point is `C^n`
403+
within the product set at the product point. -/
404+
theorem MDifferentiableWithinAt.prod_map' {p : M × N} (hf : MDifferentiableWithinAt I I' f s p.1)
405+
(hg : MDifferentiableWithinAt J J' g r p.2) :
406+
MDifferentiableWithinAt (I.prod J) (I'.prod J') (Prod.map f g) (s ×ˢ r) p :=
407+
(hf.comp p mdifferentiableWithinAt_fst (prod_subset_preimage_fst _ _)).prod_mk <|
408+
hg.comp p mdifferentiableWithinAt_snd (prod_subset_preimage_snd _ _)
409+
410+
theorem MDifferentiableWithinAt.prod_map (hf : MDifferentiableWithinAt I I' f s x)
411+
(hg : MDifferentiableWithinAt J J' g r y) :
412+
MDifferentiableWithinAt (I.prod J) (I'.prod J') (Prod.map f g) (s ×ˢ r) (x, y) :=
413+
MDifferentiableWithinAt.prod_map' hf hg
414+
415+
theorem MDifferentiableAt.prod_map
416+
(hf : MDifferentiableAt I I' f x) (hg : MDifferentiableAt J J' g y) :
417+
MDifferentiableAt (I.prod J) (I'.prod J') (Prod.map f g) (x, y) := by
418+
rw [← mdifferentiableWithinAt_univ] at *
419+
convert hf.prod_map hg
420+
exact univ_prod_univ.symm
421+
422+
/-- Variant of `MDifferentiableAt.prod_map` in which the point in the product is given as `p`
423+
instead of a pair `(x, y)`. -/
424+
theorem MDifferentiableAt.prod_map' {p : M × N}
425+
(hf : MDifferentiableAt I I' f p.1) (hg : MDifferentiableAt J J' g p.2) :
426+
MDifferentiableAt (I.prod J) (I'.prod J') (Prod.map f g) p := by
427+
rcases p with ⟨⟩
428+
exact hf.prod_map hg
429+
430+
theorem MDifferentiableOn.prod_map
431+
(hf : MDifferentiableOn I I' f s) (hg : MDifferentiableOn J J' g r) :
432+
MDifferentiableOn (I.prod J) (I'.prod J') (Prod.map f g) (s ×ˢ r) :=
433+
(hf.comp mdifferentiableOn_fst (prod_subset_preimage_fst _ _)).prod_mk <|
434+
hg.comp mdifferentiableOn_snd (prod_subset_preimage_snd _ _)
435+
436+
theorem MDifferentiable.prod_map (hf : MDifferentiable I I' f) (hg : MDifferentiable J J' g) :
437+
MDifferentiable (I.prod J) (I'.prod J') (Prod.map f g) := by
438+
intro p
439+
exact (hf p.1).prod_map' (hg p.2)
440+
441+
end prodMap
442+
304443
@[simp, mfld_simps]
305444
theorem tangentMap_prod_snd {p : TangentBundle (I.prod I') (M × M')} :
306445
tangentMap (I.prod I') I' Prod.snd p = ⟨p.proj.2, p.2.2⟩ := by
@@ -330,22 +469,30 @@ theorem mfderiv_prod_left {x₀ : M} {y₀ : M'} :
330469
refine (mdifferentiableAt_id.mfderiv_prod mdifferentiableAt_const).trans ?_
331470
rw [mfderiv_id, mfderiv_const, ContinuousLinearMap.inl]
332471

472+
theorem tangentMap_prod_left {p : TangentBundle I M} {y₀ : M'} :
473+
tangentMap I (I.prod I') (fun x => (x, y₀)) p = ⟨(p.1, y₀), (p.2, 0)⟩ := by
474+
simp only [tangentMap, mfderiv_prod_left, TotalSpace.mk_inj]
475+
rfl
476+
333477
theorem mfderiv_prod_right {x₀ : M} {y₀ : M'} :
334478
mfderiv I' (I.prod I') (fun y => (x₀, y)) y₀ =
335479
ContinuousLinearMap.inr 𝕜 (TangentSpace I x₀) (TangentSpace I' y₀) := by
336480
refine (mdifferentiableAt_const.mfderiv_prod mdifferentiableAt_id).trans ?_
337481
rw [mfderiv_id, mfderiv_const, ContinuousLinearMap.inr]
338482

483+
theorem tangentMap_prod_right {p : TangentBundle I' M'} {x₀ : M} :
484+
tangentMap I' (I.prod I') (fun y => (x₀, y)) p = ⟨(x₀, p.1), (0, p.2)⟩ := by
485+
simp only [tangentMap, mfderiv_prod_right, TotalSpace.mk_inj]
486+
rfl
487+
339488
/-- The total derivative of a function in two variables is the sum of the partial derivatives.
340489
Note that to state this (without casts) we need to be able to see through the definition of
341490
`TangentSpace`. -/
342491
theorem mfderiv_prod_eq_add {f : M × M' → M''} {p : M × M'}
343492
(hf : MDifferentiableAt (I.prod I') I'' f p) :
344493
mfderiv (I.prod I') I'' f p =
345-
show E × E' →L[𝕜] E'' from
346494
mfderiv (I.prod I') I'' (fun z : M × M' => f (z.1, p.2)) p +
347495
mfderiv (I.prod I') I'' (fun z : M × M' => f (p.1, z.2)) p := by
348-
dsimp only
349496
erw [mfderiv_comp_of_eq hf (mdifferentiableAt_fst.prod_mk mdifferentiableAt_const) rfl,
350497
mfderiv_comp_of_eq hf (mdifferentiableAt_const.prod_mk mdifferentiableAt_snd) rfl,
351498
← ContinuousLinearMap.comp_add,
@@ -356,6 +503,42 @@ theorem mfderiv_prod_eq_add {f : M × M' → M''} {p : M × M'}
356503
convert ContinuousLinearMap.comp_id <| mfderiv (.prod I I') I'' f (p.1, p.2)
357504
exact ContinuousLinearMap.coprod_inl_inr
358505

506+
/-- The total derivative of a function in two variables is the sum of the partial derivatives.
507+
Note that to state this (without casts) we need to be able to see through the definition of
508+
`TangentSpace`. Version in terms of the one-variable derivatives. -/
509+
theorem mfderiv_prod_eq_add_comp {f : M × M' → M''} {p : M × M'}
510+
(hf : MDifferentiableAt (I.prod I') I'' f p) :
511+
mfderiv (I.prod I') I'' f p =
512+
(mfderiv I I'' (fun z : M => f (z, p.2)) p.1) ∘L (id (ContinuousLinearMap.fst 𝕜 E E') :
513+
(TangentSpace (I.prod I') p) →L[𝕜] (TangentSpace I p.1)) +
514+
(mfderiv I' I'' (fun z : M' => f (p.1, z)) p.2) ∘L (id (ContinuousLinearMap.snd 𝕜 E E') :
515+
(TangentSpace (I.prod I') p) →L[𝕜] (TangentSpace I' p.2)) := by
516+
rw [mfderiv_prod_eq_add hf]
517+
congr
518+
· have : (fun z : M × M' => f (z.1, p.2)) = (fun z : M => f (z, p.2)) ∘ Prod.fst := rfl
519+
rw [this, mfderiv_comp (I' := I)]
520+
· simp only [mfderiv_fst, id_eq]
521+
rfl
522+
· exact hf.comp _ (mdifferentiableAt_id.prod_mk mdifferentiableAt_const)
523+
· exact mdifferentiableAt_fst
524+
· have : (fun z : M × M' => f (p.1, z.2)) = (fun z : M' => f (p.1, z)) ∘ Prod.snd := rfl
525+
rw [this, mfderiv_comp (I' := I')]
526+
· simp only [mfderiv_snd, id_eq]
527+
rfl
528+
· exact hf.comp _ (mdifferentiableAt_const.prod_mk mdifferentiableAt_id)
529+
· exact mdifferentiableAt_snd
530+
531+
/-- The total derivative of a function in two variables is the sum of the partial derivatives.
532+
Note that to state this (without casts) we need to be able to see through the definition of
533+
`TangentSpace`. Version in terms of the one-variable derivatives. -/
534+
theorem mfderiv_prod_eq_add_apply {f : M × M' → M''} {p : M × M'} {v : TangentSpace (I.prod I') p}
535+
(hf : MDifferentiableAt (I.prod I') I'' f p) :
536+
mfderiv (I.prod I') I'' f p v =
537+
mfderiv I I'' (fun z : M => f (z, p.2)) p.1 v.1 +
538+
mfderiv I' I'' (fun z : M' => f (p.1, z)) p.2 v.2 := by
539+
rw [mfderiv_prod_eq_add_comp hf]
540+
rfl
541+
359542
end Prod
360543

361544
section Arithmetic

0 commit comments

Comments
 (0)