5
$\begingroup$

With Block or Module we can specify variables local to their scope in curly brackets like this:

myFunction[x_]:=Block[{localVariable},...]

How can we do the same with compiled functions? The manual states that

Compiled code does not handle numerical precision and local variables in the same way as ordinary Wolfram Language code.

but there does not seem to be an example on how to define a local variable within the scope of a compiled function. How would a trivial minimal example look like?

$\endgroup$
3
  • 2
    $\begingroup$ You simply can use Block or Module in the body of the compiled function. It does not matter; both ways just tell Compile to make the variables local. $\endgroup$ Feb 7, 2018 at 7:50
  • $\begingroup$ @HenrikSchumacher Is it possible for a compiled function to take in an Association (dictionary in Python, map in C++) as input? Can it take as input another compiled function? Can a compiled function be recursive (call itself)? $\endgroup$
    – Leo
    Nov 21, 2020 at 13:53
  • 1
    $\begingroup$ No, Associations are not compilable. No, function pointers cannot be used as arguments of a CompiledFunction. Yes, I think recursive calls are possible (with some trick that you have to look up on this site), but I would really discourage to use them because -- IRCC -- they are realized by MainEvaluate which pretty much defeats the purpose of Compile. $\endgroup$ Nov 21, 2020 at 14:03

1 Answer 1

8
$\begingroup$

What configuration one chooses depends on the specific needs of the function one is compiling and other general considerations about the relative place and function of that piece of code in the rest of one's script/program.

With that in mind, one way to achieve what is being asked is to use With; this way, one can incorporate simple constants in a compiled function, eg

(* a compiled function with a constant *)
f = With[{alpha=3.507}, 
   Compile[{{x,_Real}}, 2*alpha-x*1.09]
 ]

The approach presented above addresses the need to use "constants* inside the compiled function; local variables that can take on different values during the lifespan of the local scope need to be introduced in a different way.

f = Compile[{{x,_Real}}, Module[{y=x+3.},
    Log[y]
   ]]

This last example, contrived as it might be, introduces the use of local variables inside a compiled function with the help of Module.

The first answer to this question, has a lot of packed information on the use of Compile; there are also examples of uses with compilation that uses local variables.

Also, as a side-note, the first answer to this question demonstrates the various scoping structures available in Mathematica. I include this last link, although it is not directly related to compilation, because the question involves the use of Block; I have refrained from using it in this answer, as the linked response suggests that it should be used in those cases it is absolutely necessasary to, otherwise Module will suffice.

$\endgroup$
2
  • $\begingroup$ On this topic, I am having trouble using Compile. Why does the code f:=Compile[{{M,_Integer,2},{m,_Integer}}, Module[{l},l=ConstantArray[{},m]; l[[M[[1]]]]=Transpose@{M[[2]]}; l] ]; f[{{8,9,10},{2,3,1}},10] return CompiledFunction::cfn: Numerical error encountered at instruction 8; proceeding with uncompiled evaluation.? $\endgroup$
    – Leo
    Nov 21, 2020 at 13:44
  • 1
    $\begingroup$ @Leo 1. usually a Compile function is Set not SetDelayed much like you'd do with a Function but that's not what's causing you trouble. 2. you are using Compile in order to perform some structural transformation on the input while usually Compile is used to speed up numerical calculations, but that's not either why you're having trouble 3. Compile complains because it doesn't know how to treat ConstantArray[{}, m] which, in your example, resembles a $10\times0$ matrix. One way you can avoid the message is by writing instead ConstantArray[{0}, m]. Hope this makes sense... $\endgroup$ Dec 1, 2020 at 21: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.