3
$\begingroup$

I need to compile functions for an expression and its derivative and then pass these on to a precompiled worker loop for further processing. An If statment detects when the expression parameter expr has changed and then recompiles the functions before passing them on to the worker loop. The logic for the If statement works (simplified below), and the compilation of cFastFunc works. But compilation of derivative cFastFuncPrim throws all sorts of error messages whatever I try. Either it says D is not compilable, or it complains about Function, or something else. How to do it please?

My stub for fFast looks like this:

fFast[expr_ , a_ ?NumericQ, t_ ?NumericQ, n_?NumericQ] := (
   (*Recompile the function and its derivative if it has changed*)
   If[(ConditionDetectingIfExprHasChanged),
    cFastFunc = FunctionCompile[Function[Typed[x, "Real64"], expr]]; (* OK *)
    cFastFuncPrim = FunctionCompile[Function[Typed[x, "Real64"], Function @@ {x, D[expr, x]}]];  (* Problem! *)
   ]; (* End IF *)
   cFastWorker[cFastFunc, cFastFuncPrim, a, t, n] (* TBD - Precompiled worker loop*)
   );
$\endgroup$

2 Answers 2

3
$\begingroup$

In addition to what Domen wrote in their post, I strongly recommend to scope the variable in the expression to make all this less brittle. Currently, some user of your code simply needs to assign some value to the variable x and everything will break.

So instead of handing over an expression dependent on x, rather hand over a Function. Then compute the derivative by using a scoped variable x like so:

f = x |-> x^2;

compileDerivative[f_] := Block[{x},
   With[{Df = D[f[x], x]},
    FunctionCompile[Function[Typed[x, "Real64"], Df]]
    ]
   ];
$\endgroup$
2
  • $\begingroup$ Thank you, works great $\endgroup$
    – Mikl
    Apr 2 at 20:01
  • $\begingroup$ You're welcome. $\endgroup$ Apr 2 at 22:27
2
$\begingroup$

First, remove the second Function, because you already have the Function wrapper. Second, because D is not supported by the compiler, you have to calculate the derivative in the main kernel, and insert the result into FunctionCompile. For example:

expr = x^2;
cFastFuncPrim = With[{df = D[expr, x]}, 
  FunctionCompile[Function[Typed[x, "Real64"], df]]]

cFastFuncPrim[3]
(* 6. *)
$\endgroup$
1
  • $\begingroup$ Thank you Domen $\endgroup$
    – Mikl
    Apr 2 at 20:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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