Compute Hessian of function symbolically

This question could equally apply to the computation of other symbolic transformations of a function, but I use the Hessian as an example here.

Consider a two-variable function fun which could be defined either using down-values or as a Function. It may or may not contain symbolic parameters.

Compute the Hessian of fun and return it as a Function. The symbolic computation must already be done and the result embedded in the result function. This function will be used for multiple numerical evaluations later.

One possible way to do this is:

hessian[fun_] :=
Block[{hess, x, y},
Function[{x, y}, hess] /. hess -> D[fun[x, y], {{x, y}, 2}]
]

What's wrong with this? Consider cases when fun may contain parameters (which in my case will usually be global variables with their value already set). What if these conflict with the Block variables?

x = 5;
hessian[Function[{a, b}, x a^3 + b^3]]
(* Function[{x, y}, {{12 x^2, 0}, {0, 6 y}}] *)

p = 5;
hessian[Function[{a, b}, p a^3 + b^3]]
(* Function[{x, y}, {{30 x, 0}, {0, 6 y}}] *)

One workaround is to make these live in a context that is not user-accessible, e.g.

hessian[fun_] :=
Block[{hessianhess, hessianx, hessiany},
Function[{hessianx, hessiany}, hessianhess] /.
hessianhess ->
D[fun[hessianx, hessiany], {{hessianx, hessiany}, 2}]]

But this is getting ugly quickly. What is a better way?

• I tagged this code-generation, but it isn't really code that I am generating. It is symbolic expressions with a mathematical meaning. – Szabolcs Aug 8 '16 at 10:50
• @Kuba Looks good I think – Szabolcs Aug 8 '16 at 11:24
• – Jens Aug 22 '16 at 23:07

I think this should be fine, the full form doesn't look neat with x$123 etc but that doesn't matter: hessian[fun_] := Module[{x, y}, Function @@ {{x, y}, D[fun[x, y], {{x, y}, 2}]} ] this will work too: ... Function[{x, y}, Evaluate @ D[fun[x, y], {{x, y}, 2}]] ... and will work even nicer because the outer Module will rename Function's variables to x$ without numbers.

Is this not a good place to use Formal Symbols? A number of built-ins do that.(1)

hessian[fun_] :=
Function @@ {{\[FormalX], \[FormalY]},
D[fun[\[FormalX], \[FormalY]], {{\[FormalX], \[FormalY]}, 2}]}

x = 5;
hessian[Function[{a, b}, x a^3 + b^3]]

p = 5;
hessian[Function[{a, b}, p a^3 + b^3]]

Very closely related:

e.g. Kuba's answer is essentially a duplicate, and if it really satisfies your needs I think this question should also be marked as a duplicate.

• thank you for another revelation that is so useful. I am sorry if I annoyed or irritated you re: recurring decimal representation. You almost certainly have seen this. If not I hope you derive some amusement. :) – ubpdqn Aug 23 '16 at 2:47
• I did think of this, but I didn't want to use it because what prevents someone in principle from using a formal symbol as a "parameter" in their function? Of course such a parameter is not settable to a value, but it's always Replaceable. For my personal purposes it works well, but I wouldn't have felt fully comfortable about using it in a public package. Maybe my worries were not warranted. There are builtins that return formal symbols exactly this way (jut can't remember which right now). +1. – Szabolcs Aug 23 '16 at 7:17
• @ubpdqn I don't know how I might have given you the impression that I could be annoyed but I certainly am not. :-) I have seen the video and I found it outstanding, as you might have guessed from my choice of profile picture. As always you are welcome and thanks for letting me know that you found this useful. – Mr.Wizard Aug 23 '16 at 7:22
• @Szabolcs I suppose almost anything can be broken; Leonid has shown me again and again that there can be holes in my code. However I am not sure how far it is reasonable to take things to plug all these holes. Built-in functions sometimes also break is if given certain input. Might it be acceptable to simply tell users don't use these particular formal symbols? Or maybe hessian[fun_] := Function[{\[FormalX], \[FormalY]}, Evaluate @ D[fun[\[FormalX], \[FormalY]], {{\[FormalX], \[FormalY]}, 2}]] suits your needs as it does the \$ renaming? If not maybe hessian after all. – Mr.Wizard Aug 23 '16 at 7:29
• @Szabolcs By the way I linked to one of those built-ins in the superscript link in the first line. Or do you not count that as a valid example? – Mr.Wizard Aug 23 '16 at 7:30