Imports
/- Copyright (c) 2026 Bjørn Kjos-Hanssen. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Bjørn Kjos-Hanssen -/ module public import Mathlib.Analysis.Calculus.Gradient.Basic public import Mathlib.Analysis.Calculus.ContDiff.FTaylorSeries public import Mathlib.LinearAlgebra.QuadraticForm.Basic public import Mathlib.Analysis.Calculus.FDeriv.Analytic public import Mathlib.Analysis.Analytic.IteratedFDeriv public import Mathlib.Analysis.Calculus.FDeriv.Symmetric public import Mathlib.Analysis.InnerProductSpace.PiL2

The Second Partial Derivatives Test

We prove a version of the second partial derivative test from calculus for analytic functions f : V → ℝ, where V is a finite-dimensional vector space.

Main results

    second_derivative_test: Suppose f is a real-valued function on a finite-dimensional inner product space that has vanishing gradient at x₀, and has a power series on a ball of positive radius around x₀. If the second Frechét derivative is positive definite at x₀ then f has local minimum at x₀.

Tags

partial derivative test, calculus

@[expose] public section

Update a vector of length 2 in coordinate 0.

@[simp] lemma Function.update₀ {α : Type*} {a b c : α} : Function.update ![a,b] 0 c = ![c,b] := α:Type u_1a:αb:αc:αupdate ![a, b] 0 c = ![c, b] α:Type u_1a:αb:αc:αi:Fin (Nat.succ 0).succupdate ![a, b] 0 c i = ![c, b] i; α:Type u_1a:αb:αc:αupdate ![a, b] 0 c ((fun i => i) 0, ) = ![c, b] ((fun i => i) 0, )α:Type u_1a:αb:αc:αupdate ![a, b] 0 c ((fun i => i) 1, ) = ![c, b] ((fun i => i) 1, ) α:Type u_1a:αb:αc:αupdate ![a, b] 0 c ((fun i => i) 0, ) = ![c, b] ((fun i => i) 0, )α:Type u_1a:αb:αc:αupdate ![a, b] 0 c ((fun i => i) 1, ) = ![c, b] ((fun i => i) 1, ) All goals completed! 🐙

Update a vector of length 2 in coordinate 1.

@[simp] lemma Function.update₁ {α : Type*} {a b c : α} : Function.update ![a,b] 1 c = ![a,c] := α:Type u_1a:αb:αc:αupdate ![a, b] 1 c = ![a, c] α:Type u_1a:αb:αc:αi:Fin (Nat.succ 0).succupdate ![a, b] 1 c i = ![a, c] i; α:Type u_1a:αb:αc:αupdate ![a, b] 1 c ((fun i => i) 0, ) = ![a, c] ((fun i => i) 0, )α:Type u_1a:αb:αc:αupdate ![a, b] 1 c ((fun i => i) 1, ) = ![a, c] ((fun i => i) 1, ) α:Type u_1a:αb:αc:αupdate ![a, b] 1 c ((fun i => i) 0, ) = ![a, c] ((fun i => i) 0, )α:Type u_1a:αb:αc:αupdate ![a, b] 1 c ((fun i => i) 1, ) = ![a, c] ((fun i => i) 1, ) All goals completed! 🐙

.

def QuadraticMap.toMultilinearMap {V : Type*} [AddCommGroup V] [Module V] (Q : QuadraticMap V ) : MultilinearMap (fun _ : Fin 2 => V) := { toFun := fun v => Q.polarBilin (v 0) (v 1) map_update_add' := V:Type u_1inst✝¹:AddCommGroup Vinst✝:Module VQ:QuadraticMap V [inst : DecidableEq (Fin 2)] (m : Fin 2 V) (i : Fin 2) (x y : V), (Q.polarBilin (update m i (x + y) 0)) (update m i (x + y) 1) = (Q.polarBilin (update m i x 0)) (update m i x 1) + (Q.polarBilin (update m i y 0)) (update m i y 1) All goals completed! 🐙 map_update_smul' := V:Type u_1inst✝¹:AddCommGroup Vinst✝:Module VQ:QuadraticMap V [inst : DecidableEq (Fin 2)] (m : Fin 2 V) (i : Fin 2) (c : ) (x : V), (Q.polarBilin (update m i (c x) 0)) (update m i (c x) 1) = c (Q.polarBilin (update m i x 0)) (update m i x 1) All goals completed! 🐙}

The multilinear map associated to a quadratic map is continuous.

V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional VQ:QuadraticMap V B:V →ₗ[] V →L[] hB: (x y : V), (B x) y = Q.toMultilinearMap ![x, y]hB_cont:Continuous BContinuous Q.toMultilinearMap V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional VQ:QuadraticMap V B:V →ₗ[] V →L[] hB: (x y : V), (B x) y = Q.toMultilinearMap ![x, y]hB_cont:Continuous BQ.toMultilinearMap = fun x => ((B fun v => v 0) x) (x 1); All goals completed! 🐙

.

V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional VQ:QuadraticMap V B:V →ₗ[] V →L[] hB: (x y : V), (B x) y = Q.toMultilinearMapHalfPolarBilin ![x, y]hB_cont:Continuous BContinuous Q.toMultilinearMapHalfPolarBilin V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional VQ:QuadraticMap V B:V →ₗ[] V →L[] hB: (x y : V), (B x) y = Q.toMultilinearMapHalfPolarBilin ![x, y]hB_cont:Continuous BQ.toMultilinearMapHalfPolarBilin = fun x => ((B fun v => v 0) x) (x 1); All goals completed! 🐙

Construct a continuous multilinear map from a quadratic map on a finite dimensional space.

def QuadraticMap.toContinuousMultilinearMap {V : Type*} [NormedAddCommGroup V] [NormedSpace V] [FiniteDimensional V] (Q : QuadraticMap V ) : ContinuousMultilinearMap (fun _ : Fin 2 V) := { Q.toMultilinearMap with cont := Q.toMultilinearMap_continuous }

The constructed continuous multilinear map agrees with the polar bilinear form.

theorem QuadraticMap.toContinuousMultilinearMap_apply {V : Type*} [NormedAddCommGroup V] [NormedSpace V] [FiniteDimensional V] (Q : QuadraticMap V ) (x y : V) : Q.toContinuousMultilinearMap ![x, y] = Q.polarBilin x y := V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional VQ:QuadraticMap V x:Vy:VQ.toContinuousMultilinearMap ![x, y] = (Q.polarBilin x) y All goals completed! 🐙

.

theorem QuadraticMap.toContinuousMultilinearMap_applyHalf {V : Type*} [NormedAddCommGroup V] [NormedSpace V] [FiniteDimensional V] (Q : QuadraticMap V ) (x y : V) : Q.toContinuousMultilinearMapHalfPolarBilin ![x, y] = (1/2) * Q.polarBilin x y := V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional VQ:QuadraticMap V x:Vy:VQ.toContinuousMultilinearMapHalfPolarBilin ![x, y] = 1 / 2 * (Q.polarBilin x) y All goals completed! 🐙

.

V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional VF:QuadraticMap V hf':F.PosDefhnt:Nontrivial Vthis✝:Nontrivial Vm:Vhm:m = 1 (a : V), a = 1 F.toContinuousMultilinearMapHalfPolarBilin ![m, m] F.toContinuousMultilinearMapHalfPolarBilin ![a, a]u:Vhu:¬u = 0h₁:u * u⁻¹ = 1h₂:F.toContinuousMultilinearMapHalfPolarBilin ![u⁻¹ u, u⁻¹ u] = u⁻¹ * F.toContinuousMultilinearMapHalfPolarBilin ![u⁻¹ u, u]this:F.toContinuousMultilinearMapHalfPolarBilin ![u, u] * u⁻¹ = F.toContinuousMultilinearMapHalfPolarBilin ![u⁻¹ u, u]u * u⁻¹ = u * u⁻¹ V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional VF:QuadraticMap V hf':F.PosDefhnt:Nontrivial Vthis✝:Nontrivial Vm:Vhm:m = 1 (a : V), a = 1 F.toContinuousMultilinearMapHalfPolarBilin ![m, m] F.toContinuousMultilinearMapHalfPolarBilin ![a, a]u:Vhu:¬u = 0h₁:u * u⁻¹ = 1h₂:F.toContinuousMultilinearMapHalfPolarBilin ![u⁻¹ u, u⁻¹ u] = u⁻¹ * F.toContinuousMultilinearMapHalfPolarBilin ![u⁻¹ u, u]this:F.toContinuousMultilinearMapHalfPolarBilin ![u, u] * u⁻¹ = F.toContinuousMultilinearMapHalfPolarBilin ![u⁻¹ u, u]u⁻¹ = u⁻¹ V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional VF:QuadraticMap V hf':F.PosDefhnt:Nontrivial Vthis✝:Nontrivial Vm:Vhm:m = 1 (a : V), a = 1 F.toContinuousMultilinearMapHalfPolarBilin ![m, m] F.toContinuousMultilinearMapHalfPolarBilin ![a, a]u:Vhu:¬u = 0h₁:u * u⁻¹ = 1h₂:F.toContinuousMultilinearMapHalfPolarBilin ![u⁻¹ u, u⁻¹ u] = u⁻¹ * F.toContinuousMultilinearMapHalfPolarBilin ![u⁻¹ u, u]this:F.toContinuousMultilinearMapHalfPolarBilin ![u, u] * u⁻¹ = F.toContinuousMultilinearMapHalfPolarBilin ![u⁻¹ u, u]0 u⁻¹ All goals completed! 🐙)

The polar bilinear form of the second-derivative quadratic map is the symmetrized Hessian.

lemma polarBilin_iteratedFDerivQuadraticMap {V : Type*} [NormedAddCommGroup V] [NormedSpace V] (f : V ) (x₀ : V) (x y : V) : (iteratedFDerivQuadraticMap f x₀).polarBilin x y = iteratedFDeriv 2 f x₀ ![x, y] + iteratedFDeriv 2 f x₀ ![y, x] := V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vx:Vy:V((iteratedFDerivQuadraticMap f x₀).polarBilin x) y = (iteratedFDeriv 2 f x₀) ![x, y] + (iteratedFDeriv 2 f x₀) ![y, x] V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vx:Vy:V({ toFun := fun y => (iteratedFDeriv 2 f x₀) ![y, y], toFun_smul := , exists_companion' := }.polarBilin x) y = (iteratedFDeriv 2 f x₀) ![x, y] + (iteratedFDeriv 2 f x₀) ![y, x]; V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vx:Vy:V(iteratedFDeriv 2 f x₀) ![x + y, x + y] - (iteratedFDeriv 2 f x₀) ![x, x] - (iteratedFDeriv 2 f x₀) ![y, y] = (iteratedFDeriv 2 f x₀) ![x, y] + (iteratedFDeriv 2 f x₀) ![y, x]; V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vx:Vy:V((fderiv (fun y => fderiv f y) x₀) (Fin.init ![x + y, x + y] 0)) x + ((fderiv (fun y => fderiv f y) x₀) (Fin.init ![x + y, x + y] 0)) y = ((fderiv (fun y => fderiv f y) x₀) (Fin.init ![x, y] 0)) y + ((fderiv (fun y => fderiv f y) x₀) (Fin.init ![y, x] 0)) x + ((fderiv (fun y => fderiv f y) x₀) (Fin.init ![y, y] 0)) y + ((fderiv (fun y => fderiv f y) x₀) (Fin.init ![x, x] 0)) x; V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vx:Vy:V((fderiv (fun y => fderiv f y) x₀) x) x + ((fderiv (fun y => fderiv f y) x₀) y) x + (((fderiv (fun y => fderiv f y) x₀) x) y + ((fderiv (fun y => fderiv f y) x₀) y) y) = ((fderiv (fun y => fderiv f y) x₀) x) y + ((fderiv (fun y => fderiv f y) x₀) y) x + ((fderiv (fun y => fderiv f y) x₀) y) y + ((fderiv (fun y => fderiv f y) x₀) x) x; All goals completed! 🐙

Symmetry of the second iterated Fréchet derivative (Schwarz's theorem).

All goals completed! 🐙; V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vhf:ContDiffAt f x₀x:Vy:Vh:domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀) = iteratedFDeriv 2 f x₀(iteratedFDeriv 2 f x₀) ![y, x] = (iteratedFDeriv 2 f x₀) ![x, y] V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vhf:ContDiffAt f x₀x:Vy:Vh:domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀) = iteratedFDeriv 2 f x₀(iteratedFDeriv 2 f x₀) ![x, y] = (domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀)) ![y, x]; V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vhf:ContDiffAt f x₀x:Vy:Vh:domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀) = iteratedFDeriv 2 f x₀(iteratedFDeriv 2 f x₀) ![x, y] = (iteratedFDeriv 2 f x₀) fun i => ![y, x] i.rev exact congr_arg _ (V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vhf:ContDiffAt f x₀x:Vy:Vh:domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀) = iteratedFDeriv 2 f x₀![x, y] = fun i => ![y, x] i.rev V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vhf:ContDiffAt f x₀x:Vy:Vh:domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀) = iteratedFDeriv 2 f x₀i:Fin (succ 1)![x, y] i = ![y, x] i.rev; V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vhf:ContDiffAt f x₀x:Vy:Vh:domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀) = iteratedFDeriv 2 f x₀![x, y] ((fun i => i) 0, ) = ![y, x] ((fun i => i) 0, ).revV:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vhf:ContDiffAt f x₀x:Vy:Vh:domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀) = iteratedFDeriv 2 f x₀![x, y] ((fun i => i) 1, ) = ![y, x] ((fun i => i) 1, ).rev V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vhf:ContDiffAt f x₀x:Vy:Vh:domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀) = iteratedFDeriv 2 f x₀![x, y] ((fun i => i) 0, ) = ![y, x] ((fun i => i) 0, ).revV:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vhf:ContDiffAt f x₀x:Vy:Vh:domDomCongr Fin.revPerm (iteratedFDeriv 2 f x₀) = iteratedFDeriv 2 f x₀![x, y] ((fun i => i) 1, ) = ![y, x] ((fun i => i) 1, ).rev All goals completed! 🐙)

Positive definiteness implies coercivity. The proof uses the general fact coercive_of_posdefHalf but requires a differentiability assumption on f.

V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional Vf:V x₀:Vhf:ContDiffAt f x₀hf':(iteratedFDerivQuadraticMap f x₀).PosDefkey: (x y : V), (iteratedFDerivQuadraticMap f x₀).toContinuousMultilinearMapHalfPolarBilin ![x, y] = (iteratedFDeriv 2 f x₀) ![x, y]heq:continuousBilinearMapOfContinuousMultilinearMap (iteratedFDerivQuadraticMap f x₀).toContinuousMultilinearMapHalfPolarBilin = continuousBilinearMapOfContinuousMultilinearMap (iteratedFDeriv 2 f x₀)IsCoercive (continuousBilinearMapOfContinuousMultilinearMap (iteratedFDerivQuadraticMap f x₀).toContinuousMultilinearMapHalfPolarBilin) All goals completed! 🐙

Positive definiteness implies coercivity.

V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional Vf:V x₀:Vhf':(iteratedFDerivQuadraticMap f x₀).PosDefhnt:Nontrivial Vthis✝:Nontrivial Vm:Vhm:m = 1 (a : V), a = 1 (iteratedFDeriv 2 f x₀) ![m, m] (iteratedFDeriv 2 f x₀) ![a, a]u:Vhu:¬u = 0h₁:u * u⁻¹ = 1h₂:(iteratedFDeriv 2 f x₀) ![u⁻¹ u, u⁻¹ u] = u⁻¹ * (iteratedFDeriv 2 f x₀) ![u⁻¹ u, u]this:(iteratedFDeriv 2 f x₀) ![u, u] * u⁻¹ = (iteratedFDeriv 2 f x₀) ![u⁻¹ u, u]u * u⁻¹ = u * u⁻¹ V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional Vf:V x₀:Vhf':(iteratedFDerivQuadraticMap f x₀).PosDefhnt:Nontrivial Vthis✝:Nontrivial Vm:Vhm:m = 1 (a : V), a = 1 (iteratedFDeriv 2 f x₀) ![m, m] (iteratedFDeriv 2 f x₀) ![a, a]u:Vhu:¬u = 0h₁:u * u⁻¹ = 1h₂:(iteratedFDeriv 2 f x₀) ![u⁻¹ u, u⁻¹ u] = u⁻¹ * (iteratedFDeriv 2 f x₀) ![u⁻¹ u, u]this:(iteratedFDeriv 2 f x₀) ![u, u] * u⁻¹ = (iteratedFDeriv 2 f x₀) ![u⁻¹ u, u]u⁻¹ = u⁻¹ V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:NormedSpace Vinst✝:FiniteDimensional Vf:V x₀:Vhf':(iteratedFDerivQuadraticMap f x₀).PosDefhnt:Nontrivial Vthis✝:Nontrivial Vm:Vhm:m = 1 (a : V), a = 1 (iteratedFDeriv 2 f x₀) ![m, m] (iteratedFDeriv 2 f x₀) ![a, a]u:Vhu:¬u = 0h₁:u * u⁻¹ = 1h₂:(iteratedFDeriv 2 f x₀) ![u⁻¹ u, u⁻¹ u] = u⁻¹ * (iteratedFDeriv 2 f x₀) ![u⁻¹ u, u]this:(iteratedFDeriv 2 f x₀) ![u, u] * u⁻¹ = (iteratedFDeriv 2 f x₀) ![u⁻¹ u, u]0 u⁻¹ All goals completed! 🐙)

.

V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:InnerProductSpace Vf:V x₀:Vx:VC:hx:C * x - x₀ ^ 2 (iteratedFDeriv 2 f x₀) fun x_1 => x - x₀hx₀:(fderiv f x₀) x = (fderiv f x₀) x₀h₁:f x - i range 3, 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀ C / 2 * x - x₀ ^ 2rev_ineq: {a b c d : }, a + b c + d d b a cf x₀ f x refine rev_ineq ?_ <| mul_le_mul_of_nonneg_right (V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:InnerProductSpace Vf:V x₀:Vx:VC:hx:C * x - x₀ ^ 2 (iteratedFDeriv 2 f x₀) fun x_1 => x - x₀hx₀:(fderiv f x₀) x = (fderiv f x₀) x₀h₁:f x - i range 3, 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀ C / 2 * x - x₀ ^ 2rev_ineq: {a b c d : }, a + b c + d d b a c?m.178 ?m.179 All goals completed! 🐙) (show 0 1/2 V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:InnerProductSpace Vf:V x₀:Vx:VC:hx:C * x - x₀ ^ 2 (iteratedFDeriv 2 f x₀) fun x_1 => x - x₀hx₀:(fderiv f x₀) x = (fderiv f x₀) x₀h₁:f x - i range 3, 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀ C / 2 * x - x₀ ^ 2f x₀ f x All goals completed! 🐙) V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:InnerProductSpace Vf:V x₀:Vx:VC:hx:C * x - x₀ ^ 2 (iteratedFDeriv 2 f x₀) fun x_1 => x - x₀hx₀:(fderiv f x₀) x = (fderiv f x₀) x₀rev_ineq: {a b c d : }, a + b c + d d b a ch₁:|f x - ((2⁻¹ * (iteratedFDeriv 2 f x₀) fun x_1 => x - x₀) + ((fderiv f x₀) x - (fderiv f x₀) x₀ + f x₀))| C / 2 * x - x₀ ^ 2f x₀ + ((iteratedFDeriv 2 f x₀) fun x_1 => x - x₀) * (1 / 2) f x + C * x - x₀ ^ 2 * (1 / 2) V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:InnerProductSpace Vf:V x₀:Vx:VC:hx:C * x - x₀ ^ 2 (iteratedFDeriv 2 f x₀) fun x_1 => x - x₀hx₀:(fderiv f x₀) x = (fderiv f x₀) x₀rev_ineq: {a b c d : }, a + b c + d d b a ch₁:|f x - ((2⁻¹ * (iteratedFDeriv 2 f x₀) fun x_1 => x - x₀) + ((fderiv f x₀) x - (fderiv f x₀) x₀ + f x₀))| C / 2 * x - x₀ ^ 2this:-(f x - ((2⁻¹ * (iteratedFDeriv 2 f x₀) fun x_1 => x - x₀) + ((fderiv f x₀) x₀ - (fderiv f x₀) x₀ + f x₀))) C / 2 * x - x₀ ^ 2f x₀ + ((iteratedFDeriv 2 f x₀) fun x_1 => x - x₀) * (1 / 2) f x + C * x - x₀ ^ 2 * (1 / 2) All goals completed! 🐙

Second partial derivative test, "little oh" form.

V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:InnerProductSpace Vinst✝:FiniteDimensional Vf:V x₀:Vh₀:gradient f x₀ = 0hcd:ContDiffAt f x₀hf:(iteratedFDerivQuadraticMap f x₀).PosDefC✝:hC✝:0 < C (u : V), C * u * u ((continuousBilinearMapOfContinuousMultilinearMap (iteratedFDeriv 2 f x₀)) u) uC:hC:0 < C (u : V), C * u * u ((continuousBilinearMapOfContinuousMultilinearMap (iteratedFDeriv 2 f x₀)) u) uh: c : ⦄, 0 < c ∀ᶠ (x : V) in nhds x₀, f x - i range 3, 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀ c * x - x₀ ^ 2x:Vhx:C * x - x₀ ^ 2 (iteratedFDeriv 2 f x₀) fun x_1 => x - x₀hx₀:0 = (fderiv f x₀) x - (fderiv f x₀) x₀f x - i range 3, 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀ C / 2 * x - x₀ ^ 2 f x₀ f x All goals completed! 🐙

Having a power series implies quadratic approximation.

V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vp:FormalMultilinearSeries V r:NNRealh✝:HasFPowerSeriesOnBall f p x₀ rhbig:(fun y => f (x₀ + y) - p.partialSum 3 y) =O[nhds 0] fun y => y ^ 3h:((fun y => f (x₀ + y) - p.partialSum 3 y) fun x => x - x₀) =O[nhds x₀] ((fun y => y ^ 3) fun x => x - x₀)Filter.Tendsto (fun x => ((fun y => y ^ 3) fun x => x - x₀) x / x - x₀ ^ 2) (nhds x₀) (nhds 0)V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vp:FormalMultilinearSeries V r:NNRealh✝:HasFPowerSeriesOnBall f p x₀ rhbig:(fun y => f (x₀ + y) - p.partialSum 3 y) =O[nhds 0] fun y => y ^ 3h:((fun y => f (x₀ + y) - p.partialSum 3 y) fun x => x - x₀) =O[nhds x₀] ((fun y => y ^ 3) fun x => x - x₀)∀ᶠ (x : V) in nhds x₀, x - x₀ ^ 2 = 0 ((fun y => y ^ 3) fun x => x - x₀) x = 0 V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vp:FormalMultilinearSeries V r:NNRealh✝:HasFPowerSeriesOnBall f p x₀ rhbig:(fun y => f (x₀ + y) - p.partialSum 3 y) =O[nhds 0] fun y => y ^ 3h:((fun y => f (x₀ + y) - p.partialSum 3 y) fun x => x - x₀) =O[nhds x₀] ((fun y => y ^ 3) fun x => x - x₀)Filter.Tendsto (fun x => ((fun y => y ^ 3) fun x => x - x₀) x / x - x₀ ^ 2) (nhds x₀) (nhds 0)V:Type u_1inst✝¹:NormedAddCommGroup Vinst✝:NormedSpace Vf:V x₀:Vp:FormalMultilinearSeries V r:NNRealh✝:HasFPowerSeriesOnBall f p x₀ rhbig:(fun y => f (x₀ + y) - p.partialSum 3 y) =O[nhds 0] fun y => y ^ 3h:((fun y => f (x₀ + y) - p.partialSum 3 y) fun x => x - x₀) =O[nhds x₀] ((fun y => y ^ 3) fun x => x - x₀)∀ᶠ (x : V) in nhds x₀, x - x₀ ^ 2 = 0 ((fun y => y ^ 3) fun x => x - x₀) x = 0 All goals completed! 🐙 All goals completed! 🐙
@[nontriviality] lemma isLocalMin.of_subsingleton {V : Type*} [TopologicalSpace V] [Subsingleton V] {f : V } {x₀ : V} : IsLocalMin f x₀ := V:Type u_1inst✝¹:TopologicalSpace Vinst✝:Subsingleton Vf:V x₀:VIsLocalMin f x₀ All goals completed! 🐙

The second partial derivative test.

V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:InnerProductSpace Vinst✝:FiniteDimensional Vf:V x₀:Vp:FormalMultilinearSeries V h₀:gradient f x₀ = 0r:NNRealh₁:HasFPowerSeriesOnBall f p x₀ rhf:(iteratedFDerivQuadraticMap f x₀).PosDefa✝:Nontrivial Vh₂: (x : V) (i : ), ((p i) fun x_1 => x - x₀) = 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀h₃: (x : V), (∑ i range 3, (p i) fun x_1 => x - x₀) = i range 3, 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀IsLocalMin f x₀ V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:InnerProductSpace Vinst✝:FiniteDimensional Vf:V x₀:Vp:FormalMultilinearSeries V h₀:gradient f x₀ = 0r:NNRealh₁:HasFPowerSeriesOnBall f p x₀ rhf:(iteratedFDerivQuadraticMap f x₀).PosDefa✝:Nontrivial Vh₂: (x : V) (i : ), ((p i) fun x_1 => x - x₀) = 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀h₃: (x : V), (∑ i range 3, (p i) fun x_1 => x - x₀) = i range 3, 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀h₄: (x : V), (f x - i range 3, (p i) fun x_1 => x - x₀) = f x - i range 3, 1 / i ! * (iteratedFDeriv i f x₀) fun x_1 => x - x₀IsLocalMin f x₀ All goals completed! 🐙

A more convenient form of the second partial derivative test: it suffices that f is analytic at x₀ (so that an explicit power series need not be produced by hand).

theorem second_derivative_test_analyticAt {V : Type*} [NormedAddCommGroup V] [InnerProductSpace V] [FiniteDimensional V] {f : V } {x₀ : V} (h₀ : gradient f x₀ = 0) (han : AnalyticAt f x₀) (hf : (iteratedFDerivQuadraticMap f x₀).PosDef) : IsLocalMin f x₀ := V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:InnerProductSpace Vinst✝:FiniteDimensional Vf:V x₀:Vh₀:gradient f x₀ = 0han:AnalyticAt f x₀hf:(iteratedFDerivQuadraticMap f x₀).PosDefIsLocalMin f x₀ V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:InnerProductSpace Vinst✝:FiniteDimensional Vf:V x₀:Vh₀:gradient f x₀ = 0hf:(iteratedFDerivQuadraticMap f x₀).PosDefp:FormalMultilinearSeries V r:ENNRealhr:HasFPowerSeriesOnBall f p x₀ rIsLocalMin f x₀ V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:InnerProductSpace Vinst✝:FiniteDimensional Vf:V x₀:Vh₀:gradient f x₀ = 0hf:(iteratedFDerivQuadraticMap f x₀).PosDefp:FormalMultilinearSeries V r:ENNRealhr:HasFPowerSeriesOnBall f p x₀ rr':NNRealhr'0:0 < r'hr'lt:r' < rIsLocalMin f x₀ exact second_derivative_test h₀ (hr.mono (V:Type u_1inst✝²:NormedAddCommGroup Vinst✝¹:InnerProductSpace Vinst✝:FiniteDimensional Vf:V x₀:Vh₀:gradient f x₀ = 0hf:(iteratedFDerivQuadraticMap f x₀).PosDefp:FormalMultilinearSeries V r:ENNRealhr:HasFPowerSeriesOnBall f p x₀ rr':NNRealhr'0:0 < r'hr'lt:r' < r0 < r' All goals completed! 🐙) hr'lt.le) hf