Laplacian, Hessian, and Jacobian¶
All three operators are assembled from the same array of partial derivatives. For a scalar $f$ and vector map $F$,
$$ (\operatorname{Hess}f)_{ij}=\partial_i\partial_j f, \qquad \Delta f=\operatorname{tr}(\operatorname{Hess}f), \qquad J_F=(\partial_jF_i)_{ij}. $$
Coordinates and test fields¶
We use $f=x^2+y^2+z^2$ and $F=(x^2,y^2,z^2)$. Both have diagonal derivative matrices, which makes the expected answers easy to inspect.
declare symbol x, y, z : MathValue
def parameters : Vector MathValue := [| x, y, z |]
def scalarField : MathValue := x^2 + y^2 + z^2
def vectorField : Vector MathValue := [| x^2, y^2, z^2 |]
∂/∂ scalarField parameters
Hessian and Laplacian¶
generateTensor supplies the two free matrix indices. Taking the
trace of the resulting Hessian implements the Euclidean Laplacian.
def hessian (f : MathValue) : Matrix MathValue :=
generateTensor
(\[a, b] -> ∂/∂ (∂/∂ f parameters_a) parameters_b)
[3, 3]
def laplacian (f : MathValue) : MathValue := trace (hessian f)
hessian scalarField
laplacian scalarField
Jacobian matrix and determinant¶
The same indexed construction differentiates each component of $F$. Its determinant measures the local volume scaling.
def jacobian (v : Vector MathValue) : Matrix MathValue :=
generateTensor
(\[a, b] -> ∂/∂ v_a parameters_b)
[3, 3]
jacobian vectorField
M.det (jacobian vectorField)
The outputs are $2I_3$, $6$, and $8xyz$, respectively. They show how tensor generation, contraction, and determinant calculation express three familiar multivariable operators in a uniform way.