To create Experimental`NumericalFunction
, one needs to evaluate Experimental`CreateNumericalFunction[vars, expr, dims]
where vars
is a list of arguments, expr
- the expression from which the numerical function will be created, dims
- the dimensions of the output matrix produced by this expression. If the output is scalar, then dims
should be set to {}
.
It also accepts an optional fourth argument, a list of input types corresponding to vars
, such as {_Real, _Real}
, as can be seen in this code that creates a new NIntegrate
rule. If the fourth argument is not specified, the resulting function expects a single argument: a list of the vars
values. If the fourth argument is specified, the resulting function expects a sequence of arguments instead of a single list.
The Experimental`CreateNumericalFunction
has several options, including WorkingPrecision
, EvaluationMonitor
, StepMonitor
, Compiled
, Hessian
, Gradient
and Jacobian
which work in the same way as in FindMinimum
.
Hessian
, Gradient
and Jacobian
can be Automatic
(the default), Symbolic
or FiniteDifference
. According to the Documentation,
One of the things that NumericalFunction
does is to handle derivatives
automatically. By default, symbolic derivatives are used if they can
be found, and otherwise finite differences are used.
I tried to use the "Sparse"
suboption of Hessian
and found that it is ignored. It also has interesting options "ErrorReturn"
, "SampleArgument"
and Message
the purpose of which is unclear to me.
The created Experimental`NumericalFunction
has several properties:
f = Experimental`CreateNumericalFunction[{x, y}, {Sin[x + y], x^2 y}, {2}];
f["Properties"]
{"ArgumentDimensions", "ArgumentNames", "ArgumentUnits", "CompiledFunction",
"FunctionExpression", "InputIndexes", "InputTypes", "Properties", "ResultUnits",
"SolutionDataComponents", "WorkingPrecision"}
The most useful is that you can directly compute Gradient/Jacobian or Hessian for expr
for any numerical values of parameters:
f = Experimental`CreateNumericalFunction[{x, y}, {Sin[x + y], x^2 y}, {2}];
f["Hessian"[{1, 2}]]
f["Gradient"[{1, 2}]]
f["Jacobian"[{1, 2}]]
{{{-0.14112,-0.14112},{-0.14112,-0.14112}},{{4.,2.},{2.,0.}}}
{{-0.989992,-0.989992},{4.,1.}}
{{-0.989992,-0.989992},{4.,1.}}
When called for the first time, symbolic Hessian or Jacobian will be created (if the corresponding parameter is set to Automatic
or Symbolic
), further evaluation will be executed MUCH faster. For Experimental`NumericalFunction
Gradient
and Jacobian
options seem to do the same.
There also is NDSolve`ValidNumericalFunctionQ
which seemingly tests whether the created Experimental`NumericalFunction
is valid.
There also are some useful Message
s for Experimental`CreateNumericalFunction
defined in the file "Messages.m".
Another mentionable feature of NumericalFunction
is its first argument isn't necessarily a list of Symbol
:
f = Experimental`CreateNumericalFunction[{Subscript[x, 1], y}, {Sin[Subscript[x, 1] + y],
Subscript[x, 1]^2 y}, {2}];
f[{2, 3}]
(* {-0.958924, 12.} *)
f = Experimental`CreateNumericalFunction[{x, y}, {Sin[x + y], x^2 y}, {2}, WorkingPrecision -> 20]
. Usage:f[{2, 3}]
. See alsof["Properties"]
andOptions[Experimental
CreateNumericalFunction]. I don't really know how to take advantage of them. On small examples like
f` they do not appear to be more efficient. $\endgroup$NDSolve`StateData
Properties? It has ways of getting aNumericalFunction
from diff. eqs. $\endgroup$