7
$\begingroup$

Using Mathematica the definition of user functions , which return "pure functions" is quite easy

f[list_] := Function[t, Sin[list[[1]] t] + list[[2]] Cos[t]] Plot[f[{2, 1}][t], {t, 0, 2 Pi}] 

and often very useful. Please note the use of f[liste][time] with separated argument brackets.

My question: Is it possible to pre-compile the part f[list] in such a way that it returns a pure function object?

here a small example to clarify my question:

pg[a_(*liste *)] := Interpolation[{{0, 0}, {.4, a[[1]]}, {.8, a[[2]]}, {1, 1}} , InterpolationOrder -> 1] 

defines a polygon with two variable points. pg[a] is a pure function object which can be used to find the polygon pg[a][x]~=x

opt = NMinimize[Sum[(trapez[{a, b}][x] - x)^2, {x, 0, 1, .2}], {a, b}] 
$\endgroup$
3
  • $\begingroup$ It is not clear to me why you want to compile the creation of the actual function. Oftentimes, it will be helpful enough to create the function only once, like in f[list_] := Function[t, Evaluate[Sin[list[[1]] t] + list[[2]] Cos[t]]]; g = f[{2, 1}]; Plot[g[t], {t, 0, 2 Pi}] $\endgroup$ Commented Sep 7, 2018 at 10:59
  • $\begingroup$ Thanks! My intention is to create an approximation function , which depends on a list of paramaters. Something like Interpoaltion[data[parameters]] These parameters are evaluated in a minimization process(involving NDSOlve,NMinimize), which calls the function repeatedly. For performance issues I would like to try a compiled version. $\endgroup$ Commented Sep 7, 2018 at 11:16
  • $\begingroup$ Hm. I don't get it. Would you please try to give a more concrete example that emphasizes where the performance bottleneck is? Btw.: Compiled functions cannot return a pure function. And if complex functions such as NMinimize or NDSolve appear in the code, it is usually not a good idea to compile it. But there might be other ways to speed up your code. $\endgroup$ Commented Sep 7, 2018 at 11:26

1 Answer 1

9
$\begingroup$

Here is simple code to get you going:

Clear[inferType]; inferType[arg_Integer] := _Integer inferType[arg:_Real | _?NumericQ /; Re[arg]==arg] := _Real inferType[arg_List] /; ArrayQ[arg,_,IntegerQ]:= {_Integer,Length[Dimensions[arg]]}; inferType[arg_List] /; ArrayQ[arg,_,NumericQ] && Re[arg]==arg:= {_Real,Length[Dimensions[arg]]}; inferType[_]:= General; ClearAll[memoize, compile, $preprocessingRules] $preprocessingRules = { p: HoldPattern[Part[list:{__Integer}, part_Integer]] :> RuleCondition[p] }; memoize[fn:HoldPattern[Function[var_, body_]], General]:= compile[fn] = fn memoize[fn:HoldPattern[Function[var_, body_]], {t__} | t__] := compile[fn] = Replace[ ReplaceAll[Hold[body], $preprocessingRules], Hold[preprocessed_] :> Compile[{{var, t}}, preprocessed] ] compile[fn:HoldPattern[Function[var_, body_]]][arg_]:= memoize[fn, inferType[arg]][arg] 

And then

f[list_]:=compile[Function[t,Sin[list[[1]] t]+list[[2]] Cos[t]]] 

and

Plot[f[{2, 1}][t], {t, 0, 2 Pi}] 

You can check what function was generated by calling

?compile 

Both type-inferencer and preprocessor are very simplistic, and this is for one - argument function only, but this can be a starting point, if you want this kind of things.

$\endgroup$
6
  • 1
    $\begingroup$ Thank you for your tough answer, I will need a nonpredictable amount of time to understand it.... $\endgroup$ Commented Sep 7, 2018 at 12:20
  • $\begingroup$ @UlrichNeumann I will try to add some explanations when I get a spare moment. $\endgroup$ Commented Sep 7, 2018 at 12:55
  • $\begingroup$ Thanks again for your effort!. $\endgroup$ Commented Sep 7, 2018 at 13:02
  • $\begingroup$ What do you think about this variant Compile[{{list , _Real, 1}}, Function[t, Sin[list[[1]] t] + list[[2]] Cos[t]] &]? What is the difference to your solution? Thanks! $\endgroup$ Commented Sep 8, 2018 at 20:35
  • $\begingroup$ @UlrichNeumann The difference is that my code gets compiled dynamically, already after list variable value gets injected into Compile. Your suggestion won't work as intended, because Compile can't return a compiled pure function, and so the Function will remain uncompiled. $\endgroup$ Commented Sep 9, 2018 at 19:16

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.