I want to calculate the Hessian matrix for a function that can only be evaluated numerically. So far, I have the following (where f is just for testing):
Needs["NumericalCalculus`"]
np = 3; (* number of parameters *)
f0[{x_, y_, z_}] := x^2*y*z^3 + z + 1
(* numeric version; c to count evaluations *)
f[{pars__?NumericQ}] := (c += 1; f0[{pars}])
(* construct symmetric hessian *)
hessian[{pars__?NumericQ}] := Module[{diag, urt, temp1, temp2},
(* diagonal *)
diag = Table[
ND[f[ReplacePart[{pars}, i -> temp1]], {temp1,
2}, {pars}[[i]]], {i, 1, np}
];
(* upper right triangle *)
urt = Table[
If[j > i,
ND[ND[f[ReplacePart[{pars}, {i -> temp1, j -> temp2}]],
temp1, {pars}[[i]]], temp2, {pars}[[j]]],
0
],
{i, 1, np}, {j, 1, np}
];
(* result *)
Table[
If[i == j, diag[[i]],
If[j > 1,
urt[[i, j]],
urt[[j, i]]
]
],
{i, 1, np}, {j, 1, np}
]
];
This seems to work:
c = 0;
hessian[{3, 4, 5}] // MatrixForm
yields the expected result. But the number of function evaluations appears to be rather large (I got c = 3099). Is this normal for ND, or can the above calculation be improved?
Thank you for any answers/comments.
ND[ND[f[..]..]..]
-- the insideND
especially, for which thej
-th parametertemp2
is not numeric. I don't have an solution, yet, though. $\endgroup$