The following code calculate the Hessian --- with simplification --- for a transcendental function.

fu[x_, y_, z_] :=  x^α y^β z^γ
hes = D[#1[#2, #3, #4], {{#2, #3, #4}}, {{#2, #3, #4}}] &
hescd = hes[fu, x, y, 
    z] /. {x_^(α_ - 2) y_^β_ z_^γ_ -> U/x^2, 
    x_^(α_ - 1) y_^(β_ - 1) z_^γ_ -> U/(x y)};
hescd // MatrixForm

I would like

1) to generalize it for a vector of arbitrary dimension

2) It obviously works for any algebraic function but not for all the transcendental functions for which there is a simplification. How to rewrite it to include directly in hes the simplification?

  • 1
    $\begingroup$ Related: Quick Hessian matrix and gradient calculation? $\endgroup$ – Jens Jan 15 '17 at 20:15
  • $\begingroup$ I'm probably being dense here, but what is U? $\endgroup$ – Chris K Jan 16 '17 at 2:58
  • 1
    $\begingroup$ @ChrisK It seems to stand for the entire function. It's an odd sort of simplification for programming, but common enough in papers $\endgroup$ – Michael E2 Jan 16 '17 at 4:00
  • 1
    $\begingroup$ To be fair, the OP neglected to mention that U was supposed to be a stand-in for the entire function. $\endgroup$ – J. M.'s technical difficulties Jan 16 '17 at 17:05

This seems to work for the Cobb-Douglass function with arbitrary number of variables:

ClearAll[fu2, hess2]
fu2[x : {__}, p : {__}] := Times @@ (x^p)

hess2[fn_, x : {__}, p : {__}] := ReleaseHold[D[fn[x, p], {x, 2}] /. 
  Power[w_, Plus[k_Integer, a_]] :>  HoldForm[Power[w, k]] Power[w, a] /. fn[x, p] :> U]

hess2[fu2, {v, w, x, y, z}, {a, b, c, d, e}] // MatrixForm

Mathematica graphics

In version 10 and later versions you can use Inactive and Activate combination instead of HoldForm and ReleaseHold, that is,

hess2[fn_, x : {__}, p : {__}] := Activate[D[fn[x, p], {x, 2}] /. 
  Power[w_, Plus[k_Integer, a_]] :>  Inactive[Power[w, k]] Power[w, a] /. fn[x, p] :> U]
|improve this answer|||||

Maybe you want the following:

hess[fn_, varList__] := Simplify[D[fn @@ {varList}, {{varList}, 2}]]

The first argument is the function, and the remaining arguments are referred to by varList__. Its length is arbitrary, and the function is applied to it by @@.

I added Simplify to address your point 2). It could be replaced by FullSimplify or some other, more customized commands that depend on the specific application.


I initially only went by the title of the question. The more specific replacement in the question can be built into my original answer by adding the following rule:

hess[fn_, varList__] := U ( D[fn @@ #, {#, 2}] /. Thread[# -> 1])/
                            KroneckerProduct[#, #] &[#] &@{varList}

This maintains the calling syntax given in the question, and works for arbitrary dimensions:

fu[w_, x_, y_, z_] := w^a x^b y^c z^d

hess[fu, w, x, y, z] // MatrixForm

Mathematica graphics

The output is the same as in @MichaelE2's answer.

|improve this answer|||||
  • $\begingroup$ Jens it works and it does not work. It works because it do the trick. But it does not work since the simplification is not done. My problem is to do the suggested simplification for a fonction of any length --- not only x^α y^β z^γ but also x^[Alpha] y^[Beta] z^[Gamma] v^[Epsilon] and so on $\endgroup$ – cyrille.piatecki Jan 15 '17 at 20:40
  • $\begingroup$ @cyrille.piatecki OK, I added your specific simplification. $\endgroup$ – Jens Jan 16 '17 at 4:27

The Hessian is pretty straightforward, as pointed out by Jens. Using patterns instead of basic algebra makes the "simplification" trickier than necessary.

ClearAll[a, b, c, d, w, x, y, z, f];

f[x_List, p_List] := Inner[Power, x, p, Times];

vars = {w, x, y, z};
powers = {a, b, c, d};

D[f[vars, powers], {vars, 2}] * U/f[vars, powers] // MatrixForm

Mathematica graphics

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.