import Mathlib.Analysis.Calculus.FDeriv.Basic import Mathlib.Analysis.Calculus.FDeriv.Symmetric import Mathlib.Analysis.Calculus.ContDiff.Basic variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] variable {G : Type*} [NormedAddCommGroup G] [NormedSpace ๐•œ G] variable (๐•œ) noncomputable def 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} : partialDeriv ๐•œ (a โ€ข v) f = a โ€ข partialDeriv ๐•œ v f := by unfold partialDeriv conv => left intro w rw [map_smul] theorem partialDeriv_addโ‚ {f : E โ†’ F} {vโ‚ vโ‚‚ : E} : partialDeriv ๐•œ (vโ‚ + vโ‚‚) f = (partialDeriv ๐•œ vโ‚ f) + (partialDeriv ๐•œ vโ‚‚ f) := by unfold partialDeriv conv => left intro w rw [map_add] theorem partialDeriv_smulโ‚‚ {f : E โ†’ F} {a : ๐•œ} {v : E} (h : Differentiable ๐•œ f) : partialDeriv ๐•œ v (a โ€ข f) = a โ€ข partialDeriv ๐•œ v f := by unfold 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โ‚‚) : partialDeriv ๐•œ v (fโ‚ + fโ‚‚) = (partialDeriv ๐•œ v fโ‚) + (partialDeriv ๐•œ v fโ‚‚) := by unfold 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[๐•œ] G} {v : E} (h : Differentiable ๐•œ f) : partialDeriv ๐•œ v (l โˆ˜ f) = l โˆ˜ partialDeriv ๐•œ v f := by unfold partialDeriv conv => left intro w left rw [fderiv.comp w (ContinuousLinearMap.differentiableAt l) (h w)] simp rfl theorem partialDeriv_compContLinAt {f : E โ†’ F} {l : F โ†’L[๐•œ] G} {v : E} {x : E} (h : DifferentiableAt ๐•œ f x) : (partialDeriv ๐•œ v (l โˆ˜ f)) x = (l โˆ˜ partialDeriv ๐•œ v f) x:= by unfold partialDeriv rw [fderiv.comp x (ContinuousLinearMap.differentiableAt l) h] simp theorem partialDeriv_contDiff {n : โ„•} {f : E โ†’ F} (h : ContDiff ๐•œ (n + 1) f) : โˆ€ v : E, ContDiff ๐•œ n (partialDeriv ๐•œ v f) := by unfold 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 theorem partialDeriv_contDiffAt {n : โ„•} {f : E โ†’ F} {x : E} (h : ContDiffAt ๐•œ (n + 1) f x) : โˆ€ v : E, ContDiffAt ๐•œ n (partialDeriv ๐•œ v f) x := by unfold partialDeriv intro v let eval_at_v : (E โ†’L[๐•œ] F) โ†’L[๐•œ] F := { toFun := fun l โ†ฆ l v map_add' := by simp map_smul' := by simp } have : (fun w => (fderiv ๐•œ f w) v) = eval_at_v โˆ˜ (fun w => (fderiv ๐•œ f w)) := by rfl rw [this] apply ContDiffAt.continuousLinearMap_comp -- ContDiffAt ๐•œ (โ†‘n) (fun w => fderiv ๐•œ f w) x apply ContDiffAt.fderiv_right h rfl lemma partialDeriv_fderiv {f : E โ†’ F} (hf : ContDiff ๐•œ 2 f) (z a b : E) : fderiv ๐•œ (fderiv ๐•œ f) z b a = partialDeriv ๐•œ b (partialDeriv ๐•œ a f) z := by unfold partialDeriv rw [fderiv_clm_apply] ยท simp ยท exact (contDiff_succ_iff_fderiv.1 hf).2.differentiable le_rfl z ยท simp theorem partialDeriv_eventuallyEq {fโ‚ fโ‚‚ : E โ†’ F} {x : E} (h : fโ‚ =แถ [nhds x] fโ‚‚) : โˆ€ v : E, partialDeriv ๐•œ v fโ‚ x = partialDeriv ๐•œ v fโ‚‚ x := by unfold partialDeriv rw [Filter.EventuallyEq.fderiv_eq h] exact fun v => rfl theorem partialDeriv_eventuallyEq' {fโ‚ fโ‚‚ : E โ†’ F} {x : E} (h : fโ‚ =แถ [nhds x] fโ‚‚) : โˆ€ v : E, partialDeriv ๐•œ v fโ‚ =แถ [nhds x] partialDeriv ๐•œ v fโ‚‚ := by unfold partialDeriv intro v let A : fderiv ๐•œ fโ‚ =แถ [nhds x] fderiv ๐•œ fโ‚‚ := Filter.EventuallyEq.fderiv h apply Filter.EventuallyEq.compโ‚‚ exact A simp section restrictScalars variable (๐•œ : Type*) [NontriviallyNormedField ๐•œ] variable {๐•œ' : Type*} [NontriviallyNormedField ๐•œ'] [NormedAlgebra ๐•œ ๐•œ'] variable {E : Type*} [NormedAddCommGroup E] [NormedSpace ๐•œ E] [NormedSpace ๐•œ' E] variable [IsScalarTower ๐•œ ๐•œ' E] variable {F : Type*} [NormedAddCommGroup F] [NormedSpace ๐•œ F] [NormedSpace ๐•œ' F] variable [IsScalarTower ๐•œ ๐•œ' F] --variable {f : E โ†’ F} theorem partialDeriv_restrictScalars {f : E โ†’ F} {v : E} : Differentiable ๐•œ' f โ†’ partialDeriv ๐•œ v f = partialDeriv ๐•œ' v f := by intro hf unfold partialDeriv funext x rw [(hf x).fderiv_restrictScalars ๐•œ] simp theorem partialDeriv_comm {E : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] {F : Type*} [NormedAddCommGroup F] [NormedSpace โ„ F] {f : E โ†’ F} (h : ContDiff โ„ 2 f) : โˆ€ vโ‚ vโ‚‚ : E, partialDeriv โ„ vโ‚ (partialDeriv โ„ vโ‚‚ f) = partialDeriv โ„ vโ‚‚ (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โ‚‚]