Function Repository Resource:

TensorPureFunction

Source Notebook

Get a pure function whose argument is a vector or a matrix for a given tensor

Contributed by: E. Chan-López & Víctor Castellanos

ResourceFunction["TensorPureFunction"][t,argvars]

gives the corresponding pure function representation of a tensor t for a set of variables argvars.

ResourceFunction["TensorPureFunction"][t]

represents an operator form that can be applied to arguments.

Details

The t must be a tensor of any rank.
The argvars must be the set of variables of interest and can be either a vector or a matrix.
ResourceFunction["TensorPureFunction"][t,argvars ] can be used to obtain different functions with array arguments in the basic vector calculus and with multilinear functions to study normal forms in applied bifurcation theory.
ResourceFunction["TensorPureFunction"][t,argvars] has an option to specify the method used for indexing the elements of argvars called "IndexingMethod". This option specifies how elements of argvars are indexed within the function. By default, the indexing method for variables in argvars is done using Indexed and specifying "IndexingMethod""UsePart" uses Part as the indexing method.

Examples

Basic Examples (3) 

Define a function that takes a matrix of variables as input and returns a vector:

In[1]:=
func = ResourceFunction["TensorPureFunction"][{x^2 + y}, {x, y}]
Out[1]=

Apply the function:

In[2]:=
func[{a, b}]
Out[2]=

Use TensorPureFunction with a tensor of rank 3:

In[3]:=
t3 = ResourceFunction["TensorPureFunction"][
  D[{x^3 y - 2 x y^4 - y^6, x^2 y^2 - 5 x y^3}, {{x, y}, 2}], {x, y}]
Out[3]=

Apply the function:

In[4]:=
t3[{1, 1}] // MatrixForm
Out[4]=

Use TensorPureFunction with a tensor of rank 4:

In[5]:=
t4 = ResourceFunction["TensorPureFunction"][
  D[{x^3 y - 2 x y^4 - y^6, x^2 y^2 - 5 x y^3}, {{x, y}, 3}], {x, y}]
Out[5]=

Apply the function:

In[6]:=
t4[{1, 1}] // MatrixForm
Out[6]=

Scope (3) 

Use TensorPureFunction in combination with Grad:

In[7]:=
ResourceFunction["TensorPureFunction"][
 Grad[x y Sin[z], {x, y, z}], {x, y, z}]
Out[7]=

Use TensorPureFunction in combination with Curl:

In[8]:=
ResourceFunction["TensorPureFunction"][
 Curl[{Exp[y] Sin[w], Exp[x] Cos[w], x y}, {x, y, w}], {x, y, w}]
Out[8]=

Use TensorPureFunction to compute a Jacobian matrix:

In[9]:=
jacobian = ResourceFunction["TensorPureFunction"][
  Simplify@D[{x^3 - 2 x y - y^6, x y^2 - 5 x y}, {{x, y}}], {x, y}]
Out[9]=

Apply the Jacobian function:

In[10]:=
jacobian[{1, 1}] // MatrixForm
Out[10]=

Use TensorPureFunction to compute a Hessian matrix:

In[11]:=
hessian = ResourceFunction["TensorPureFunction"][
  D[x^3 - 2 x y - y^6, {{x, y}, 2}], {x, y}]
Out[11]=

Apply the Hessian function:

In[12]:=
hessian[{1, 1}] // MatrixForm
Out[12]=

Options (1) 

IndexingMethod (1) 

The IndexingMethod option allows specifying the method used to indexing elements of argvars in the TensorPureFunction. By default, the method is set to "UseIndexed", which uses the Indexed function. Alternatively, can be set the option to "UsePart" to use the Part function. This option provides flexibility in choosing the preferred method of indexing elements of argvars within the TensorPureFunction:

In[13]:=
With[{f = {x^3 - 2 x y, x y^2}, vars = {x, y}}, ResourceFunction["TensorPureFunction"][f, vars, "IndexingMethod" -> "UsePart"]]
Out[13]=

Applications (4) 

Multilinear Functions (2) 

Use TensorPureFunction with the following trilinear function:

In[14]:=
d3 = ResourceFunction[
  "TensorPureFunction"][{-2 x3 y1 y2 - 2 x2 y1 y3 - 2 x1 y2 y3, 4 x2 x3 y1 + 4 x1 x3 y2 + 4 x1 x2 y3}, {{x1, y1}, {x2, y2}, {x3, y3}}]
Out[14]=

Apply the trilinear function:

In[15]:=
d3[{{1, 1}, {1, 2}, {1, -1}}] // MatrixForm
Out[15]=

Deformation Gradient and Vorticity Tensor (2) 

Define a simple function to compute the deformation gradient given a velocity field at the point :

In[16]:=
DeformationGradient[velocityField_List, coordinates_List] := 1/2 (Grad[velocityField, coordinates] + Transpose[Grad[velocityField, coordinates]])

The calculation of the deformation gradient for the -velocity is as follows:

In[17]:=
u[x_, y_, z_] := {x*z, y*z, x*y}
DeformationGradient[u[x, y, z], {x, y, z}]
Out[18]=

Now, use TensorPureFunction to obtain a pure function of the above array:

In[19]:=
dg = With[{dfg = %}, ResourceFunction["TensorPureFunction"][dfg, {x, y, z}]]
Out[19]=
In[20]:=
dg[{1, 1, 1}] // MatrixForm
Out[20]=

Define a simple function to compute the vorticity tensor given a velocity field at the point :

In[21]:=
VorticityTensor[velocityField_, coordinates_List] := 1/2 (Grad[velocityField, coordinates] - Transpose[Grad[velocityField, coordinates]])

The calculation of the vorticity tensor for the -velocity is as follows:

In[22]:=
u[x_, y_, z_] := {-y*x, x*y, y*z^2}
VorticityTensor[u[x, y, z], {x, y, z}]
Out[23]=

Now, use TensorPureFunction to obtain a pure function of the above array:

In[24]:=
vt = With[{vrt = %}, ResourceFunction["TensorPureFunction"][vrt, {x, y, z}]]
Out[24]=
In[25]:=
vt[{1, 1, 1}] // MatrixForm
Out[25]=

Properties and Relations (3) 

Use TensorPureFunction with the resource function JacobianMatrix:

In[26]:=
ResourceFunction["TensorPureFunction"][
 Simplify@
  ResourceFunction["JacobianMatrix"][{x^3 - 2 x y - y^6, x y^2 - 5 x y}, {x, y}], {x, y}]
Out[26]=

This is equivalent the computing the Jacobian directly:

In[27]:=
jacobian = ResourceFunction["TensorPureFunction"][
  Simplify@D[{x^3 - 2 x y - y^6, x y^2 - 5 x y}, {{x, y}}], {x, y}]
Out[27]=
In[28]:=
% === jacobian
Out[28]=

Use TensorPureFunction with the resource function HessianMatrix:

In[29]:=
ResourceFunction["TensorPureFunction"][
 ResourceFunction["HessianMatrix"][x^3 - 2 x y - y^6, {x, y}], {x, y}]
Out[29]=

This is equivalent the computing the Hessian directly:

In[30]:=
hessian = ResourceFunction["TensorPureFunction"][
  D[x^3 - 2 x y - y^6, {{x, y}, 2}], {x, y}]
Out[30]=
In[31]:=
% === hessian
Out[31]=

Use TensorPureFunction with the resource function DVectorField:

In[32]:=
d21 = With[{ten = ResourceFunction["DVectorField"][{x - y^2, 2 y/x}, {x, y}, {1, 2},
       2, "MultilinearFunction"]}, ResourceFunction["TensorPureFunction"][ten, {{x1, y1}, {x2, y2}}]];
In[33]:=
d22 = ResourceFunction["DVectorField"][{x - y^2, 2 y/x}, {x, y}, {1, 2}, 2, "PureMultilinearFunction"];

The previous tensors are identical:

In[34]:=
SameQ[d21, d22]
Out[34]=

Possible Issues (3) 

If any of the specified variables have existing definitions, TensorPureFunction issues a warning and returns unevaluated. For example:

In[35]:=
x1 = 1;
y1 = 2;
ResourceFunction[
 "TensorPureFunction"][{-2 x3 y1 y2 - 2 x2 y1 y3 - 2 x1 y2 y3, 4 x2 x3 y1 + 4 x1 x3 y2 + 4 x1 x2 y3}, {{x1, y1}, {x2, y2}, {x3, y3}}]
Out[37]=

To avoid this issue, wrap the variables with Block to prevent conflicts with global definitions:

In[38]:=
Block[{x1, y1}, ResourceFunction[
  "TensorPureFunction"][{-2 x3 y1 y2 - 2 x2 y1 y3 - 2 x1 y2 y3, 4 x2 x3 y1 + 4 x1 x3 y2 + 4 x1 x2 y3}, {{x1, y1}, {x2, y2}, {x3, y3}}]]
Out[38]=

Since TensorPureFunction explicitly checks for global definitions before proceeding, it remains unevaluated when global definitions of the arguments are found. For example:

In[39]:=
ten = {x - y^2, 2 y/x};
vars = {x, y};
In[40]:=
ResourceFunction["TensorPureFunction"][ten, vars]
Out[40]=

Evaluate overrides the hold attribute so that TensorPureFunction behaves as expected with the previously defined inputs:

In[41]:=
ResourceFunction["TensorPureFunction"][Evaluate@ten, Evaluate@vars]
Out[41]=

On the other hand, when using Evaluate explicitly on the function or variable arguments before passing them to TensorPureFunction, and at least one of the variables in the argument list has a global definition, the expected behavior of holding evaluation and issuing a warning will not occur. Instead, the function will be evaluated with the assigned values, potentially leading to incorrect results. For example:

In[42]:=
x = 1;
ten = {x - y^2, 2 y/x};
vars = {x, y};
In[43]:=
ResourceFunction["TensorPureFunction"][Evaluate@ten, Evaluate@vars]
Out[43]=

In this case, since Evaluate forces the immediate evaluation of the input, TensorPureFunction does not detect existing global definitions and proceeds incorrectly. To avoid this issue, it is recommended to use Clear to remove any prior definitions before applying the function.

Publisher

Ramón Eduardo Chan López

Requirements

Wolfram Language 13.0 (December 2021) or above

Version History

  • 2.1.0 – 19 February 2025
  • 2.0.1 – 20 March 2024
  • 2.0.0 – 02 October 2023
  • 1.0.0 – 08 November 2022

Source Metadata

Related Resources

Author Notes

The current implementation draws inspiration from the in-depth discussion and contributions of various users on the Mathematica Stack Exchange Community in the post titled Can a pure function be constructed whose argument list is a matrix?.

License Information