I’m looking at the maximum likelihood example on the Optim.jl page and trying it on a different likelihood function (truncated normal). I’m running into an issue where the covariance matrix returned using the Optim example method is not a valid covariance matrix. However, if I directly use the ForwardDiff package I get a valid covariance matrix, leaving me quite unsure what is going wrong with the below code. Any ideas as to what is going wrong?
The example:
using Optim, Distributions
import NLSolversBase, ForwardDiff
data = [2.59 0.93 0.70 1.83 1.46 2.04 1.31 1.55 1.19 0.16 2.09 1.32 0.18 0.12 2.17 1.52 0.84 1.85 2.29 0.94 0.01 0.89 2.76 3.15 0.52 1.91 2.11 0.81 2.46 1.30];
data = adjoint(data);
function nlog_lik(y,μ,σ2)
n = length(y)
llik = -n*(log(sqrt(2*π)) + log(sqrt(σ2)) + log(1 - cdf(Normal(),-μ/sqrt(σ2)))) - 1/(2*σ2)*sum((y .- μ).^2)
nllik = -llik
return nllik
end
nlog_lik_data = TwiceDifferentiable(vars -> nlog_lik(data, vars[1], vars[2]), [1.43,1.0]; autodiff=:forward);
opt = optimize(nlog_lik_data,[1.43,1.0],store_trace=true);
param = opt.minimizer;
# not a valid variance-covariance matrix
numerical_hessian = NLSolversBase.hessian!(nlog_lik_data,param);
@show var_cov_matrix = inv(numerical_hessian)
# valid variance-covariance matrix
nlog_lik_data2 = (vars -> nlog_lik(data, vars[1], vars[2]))
numerical_hessian2 = ForwardDiff.hessian(nlog_lik_data2, param)
@show var_cov_matrix2 = inv(numerical_hessian2)
# should be the same?
var_cov_matrix = inv(numerical_hessian) = [-0.489987 1.71397; 0.360741 -0.882709]
var_cov_matrix2 = inv(numerical_hessian2) = [0.0683089 -0.0587528; -0.0587528 0.143764]