Hessians
Hessians are a crucial ingredient in NewtonSolvers and SimpleSolvers.NewtonOptimizerStates.
using SimpleSolvers
using LinearAlgebra: norm
x = rand(3)
obj = OptimizerProblem(x -> norm(x - vcat(0., 0., 1.)) ^ 2, x)
hes = HessianAutodiff(obj, x)HessianAutodiff{Float64, Main.var"#2#3", Matrix{Float64}, ForwardDiff.HessianConfig{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3}, 3}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3}}}}(Main.var"#2#3"(), [NaN NaN NaN; NaN NaN NaN; NaN NaN NaN], ForwardDiff.HessianConfig{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3}, 3}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3}}}(ForwardDiff.JacobianConfig{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3}}}((Partials(1.0, 0.0, 0.0), Partials(0.0, 1.0, 0.0), Partials(0.0, 0.0, 1.0)), ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3}[Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(0.0,0.0,5.0e-324,5.0e-324), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(1.0e-323,1.0e-323,0.0,0.0), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(1.0e-323,1.0e-323,0.0,0.0)]), ForwardDiff.GradientConfig{ForwardDiff.Tag{Main.var"#2#3", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3}, 3, Vector{ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3}, 3}}}((Partials(Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(1.0,0.0,0.0,0.0), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(0.0,0.0,0.0,0.0), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(0.0,0.0,0.0,0.0)), Partials(Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(0.0,0.0,0.0,0.0), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(1.0,0.0,0.0,0.0), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(0.0,0.0,0.0,0.0)), Partials(Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(0.0,0.0,0.0,0.0), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(0.0,0.0,0.0,0.0), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(1.0,0.0,0.0,0.0))), ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, ForwardDiff.Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}, Float64, 3}, 3}[Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.93949532233823e-310,6.9394953223398e-310,6.9394953223414e-310,6.93949532234298e-310),Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.93949532234456e-310,6.93949532234614e-310,6.93949532233665e-310,1.5217e-320),Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(NaN,6.9395378328871e-310,6.9394953222987e-310,6.93949532231294e-310),Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.9394953223319e-310,6.9394953223335e-310,6.93949532231135e-310,6.9394953223161e-310)), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.93953770387273e-310,6.9394954050377e-310,6.93949532232717e-310,6.9394953223256e-310),Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.93949532233823e-310,6.9394953223398e-310,6.9394953223414e-310,6.93949532234298e-310),Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.93949532234456e-310,6.93949532234614e-310,6.93949532233665e-310,1.5217e-320),Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(NaN,6.9395378328871e-310,6.93949531435097e-310,6.9394953143652e-310)), Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.9394953143826e-310,6.93949531438417e-310,6.9394953143636e-310,6.93949531436836e-310),Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.93953770387273e-310,6.9394954051207e-310,6.93949531437785e-310,6.93949531437627e-310),Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.9394953143889e-310,6.9394953143905e-310,6.9394953143921e-310,6.93949531439366e-310),Dual{ForwardDiff.Tag{Main.var"#2#3", Float64}}(6.93949531439524e-310,6.9394953143968e-310,6.93949531438733e-310,1.5217e-320))])))An instance of HessianAutodiff stores a Hessian matrix:
hes.H3×3 Matrix{Float64}:
NaN NaN NaN
NaN NaN NaN
NaN NaN NaNThe instance of HessianAutodiff can be called:
hes(x)3×3 Matrix{Float64}:
2.0 0.0 0.0
0.0 2.0 -1.11022e-16
5.55112e-17 1.11022e-16 2.0Or equivalently with:
update!(hes, x)This updates hes.H:
hes.H3×3 Matrix{Float64}:
2.0 0.0 0.0
0.0 2.0 -1.11022e-16
5.55112e-17 1.11022e-16 2.0BFGS Hessian
using SimpleSolvers: initialize!
hes = HessianBFGS(obj, x)
initialize!(hes, x)HessianBFGS{Float64, Vector{Float64}, Matrix{Float64}, OptimizerProblem{Float64, Vector{Float64}, Main.var"#2#3", Missing, Float64, Vector{Float64}}}(OptimizerProblem (for vector-valued quantities only the first component is printed):
f(x) = NaN
g(x)₁ = 3.82e-01
x_f₁ = NaN
x_g₁ = 1.91e-01
, [NaN, NaN, NaN], [0.19090669902576285, 0.5256623915420473, 0.3905882754313441], [NaN, NaN, NaN], [NaN, NaN, NaN], [0.3818133980515257, 1.0513247830840946, -1.2188234491373118], [NaN, NaN, NaN], [1.0 0.0 0.0; 0.0 1.0 0.0; 0.0 0.0 1.0], [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0], [0.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 0.0])For computational reasons we save the inverse of the Hessian, it can be accessed by calling inv:
inv(hes)3×3 Matrix{Float64}:
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 1.0Similarly to HessianAutodiff we can call update!:
update!(hes, x)