6
$\begingroup$

I am writing a package where a couple defined functions take a very long time define at initialization time (because they are large CompiledFunctions).

However since these functions are not meant to be used frequently, I would like to defer making its definition until the user calls it the first time.

Suppose my package looks like this:

BeginPackage["MyPackage`"]

BigFunction::usage = "BigFunciton[a,b] computes a+b.  
   But, this function will initialize only when it is first called.";

Begin["Private`"];

  (*Need to delay this definition until it is first called.*)

  BigFunction = Compile[{{a,_Real},{b,_Real}},a+b];

End[];

EndPackage[]

How do I delay the definition of the function BigFunction until it is first called by the user?

$\endgroup$
  • 4
    $\begingroup$ BigFunction := BigFunction = Compile... $\endgroup$ – halirutan Oct 1 '15 at 13:05
7
$\begingroup$

As shown in my comment, what I usually do is defer the compilation of the function until it is first used. Once your function is compiled, you store it in exact the same variable and therefore, you only have a delay in the very first call.

This method is basically just a simple memoization and I use it very often in packages. For instance in my Heyex Data Import:

$adjustGraylevelFunc := ($adjustGraylevelFunc = Compile[{{values, _Real, 2}},
  Map[...],
  ...
])

Please note that this kind of runtime-generation of compiled code can be extended. For instance if your compiled function depends on an expression that you only know when the function is called, then you can create a personalized compiled function every time you need it.

To give a specific example. Let's assume you compile a finite differences scheme, then you could make it more flexible by giving the opportunity to create compiled functions that use different schemes, like forward or centered differences.

$\endgroup$
  • $\begingroup$ This is wonderful; I am wondering if you know what to do if the function definition that needs to be delayed is not compiled but has a pattern-based downvalue. Something like f[x_]:=f[x_]=x^2 seems not to work because you can't have patterns on both sides of SetDelayed. $\endgroup$ – QuantumDot Oct 4 '15 at 10:29
  • $\begingroup$ Can you describe the use-case of this? What exactly are you trying to achieve? $\endgroup$ – halirutan Oct 4 '15 at 16:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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