import Mathlib.Data.Fin.Tuple.Basic import Mathlib.Analysis.Complex.Basic import Mathlib.Analysis.Complex.TaylorSeries import Mathlib.Analysis.Calculus.LineDeriv.Basic import Mathlib.Analysis.Calculus.ContDiff.Basic import Mathlib.Analysis.Calculus.ContDiff.Defs import Mathlib.Analysis.Calculus.FDeriv.Basic import Mathlib.Analysis.Calculus.FDeriv.Comp import Mathlib.Analysis.Calculus.FDeriv.Linear import Mathlib.Analysis.Calculus.FDeriv.Symmetric variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] variable {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace โ„ F] noncomputable def Real.partialDeriv : E โ†’ (E โ†’ F) โ†’ (E โ†’ F) := fun v โ†ฆ (fun f โ†ฆ (fun w โ†ฆ fderiv โ„ f w v)) theorem partialDeriv_smulโ‚ {f : E โ†’ F} {a : โ„} {v : E} : Real.partialDeriv (a โ€ข v) f = a โ€ข Real.partialDeriv v f := by unfold Real.partialDeriv conv => left intro w rw [map_smul] theorem partialDeriv_addโ‚ {f : E โ†’ F} {vโ‚ vโ‚‚ : E} : Real.partialDeriv (vโ‚ + vโ‚‚) f = (Real.partialDeriv vโ‚ f) + (Real.partialDeriv vโ‚‚ f) := by unfold Real.partialDeriv conv => left intro w rw [map_add] theorem partialDeriv_smulโ‚‚ {f : E โ†’ F} {a : โ„} {v : E} (h : Differentiable โ„ f) : Real.partialDeriv v (a โ€ข f) = a โ€ข Real.partialDeriv v f := by unfold Real.partialDeriv have : a โ€ข f = fun y โ†ฆ a โ€ข f y := by rfl rw [this] conv => left intro w rw [fderiv_const_smul (h w)] theorem partialDeriv_addโ‚‚ {fโ‚ fโ‚‚ : E โ†’ F} {v : E} (hโ‚ : Differentiable โ„ fโ‚) (hโ‚‚ : Differentiable โ„ fโ‚‚) : Real.partialDeriv v (fโ‚ + fโ‚‚) = (Real.partialDeriv v fโ‚) + (Real.partialDeriv v fโ‚‚) := by unfold Real.partialDeriv have : fโ‚ + fโ‚‚ = fun y โ†ฆ fโ‚ y + fโ‚‚ y := by rfl rw [this] conv => left intro w left rw [fderiv_add (hโ‚ w) (hโ‚‚ w)] theorem partialDeriv_compContLin {f : E โ†’ F} {l : F โ†’L[โ„] F} {v : E} (h : Differentiable โ„ f) : Real.partialDeriv v (l โˆ˜ f) = l โˆ˜ Real.partialDeriv v f := by unfold Real.partialDeriv conv => left intro w left rw [fderiv.comp w (ContinuousLinearMap.differentiableAt l) (h w)] simp rfl theorem partialDeriv_contDiff {n : โ„•} {f : E โ†’ F} (h : ContDiff โ„ (n + 1) f) : โˆ€ v : E, ContDiff โ„ n (Real.partialDeriv v f) := by unfold Real.partialDeriv intro v let A := (contDiff_succ_iff_fderiv.1 h).right simp at A have : (fun w => (fderiv โ„ f w) v) = (fun f => f v) โˆ˜ (fun w => (fderiv โ„ f w)) := by rfl rw [this] refine ContDiff.comp ?hg A refine ContDiff.of_succ ?hg.h refine ContDiff.clm_apply ?hg.h.hf ?hg.h.hg exact contDiff_id exact contDiff_const lemma partialDeriv_fderiv {f : E โ†’ F} (hf : ContDiff โ„ 2 f) (z a b : E) : fderiv โ„ (fderiv โ„ f) z b a = Real.partialDeriv b (Real.partialDeriv a f) z := by unfold Real.partialDeriv rw [fderiv_clm_apply] ยท simp ยท exact (contDiff_succ_iff_fderiv.1 hf).2.differentiable le_rfl z ยท simp theorem partialDeriv_comm {f : E โ†’ F} (h : ContDiff โ„ 2 f) : โˆ€ vโ‚ vโ‚‚ : E, Real.partialDeriv vโ‚ (Real.partialDeriv vโ‚‚ f) = Real.partialDeriv vโ‚‚ (Real.partialDeriv vโ‚ f) := by intro vโ‚ vโ‚‚ funext z have derivSymm : (fderiv โ„ (fun w => fderiv โ„ f w) z) vโ‚ vโ‚‚ = (fderiv โ„ (fun w => fderiv โ„ f w) z) vโ‚‚ vโ‚ := by let f' := fderiv โ„ f have hโ‚€ : โˆ€ y, HasFDerivAt f (f' y) y := by intro y exact DifferentiableAt.hasFDerivAt ((h.differentiable one_le_two) y) let f'' := (fderiv โ„ f' z) have hโ‚ : HasFDerivAt f' f'' z := by apply DifferentiableAt.hasFDerivAt apply (contDiff_succ_iff_fderiv.1 h).right.differentiable (Submonoid.oneLE.proof_2 โ„•โˆž) apply second_derivative_symmetric hโ‚€ hโ‚ vโ‚ vโ‚‚ rw [โ† partialDeriv_fderiv h z vโ‚‚ vโ‚] rw [derivSymm] rw [partialDeriv_fderiv h z vโ‚ vโ‚‚]