How to create Functions that have Compiled functions effectively
Here's one possibility. Write out the body as a separate block wrapped in Hold[]
, and then use either of Compile[]
or Function[]
as needed. This approach has been used in some of the add-on packages that accompany Mathematica:
(* for more complicated cases, you'd have something like Hold[Module[(* stuff *)]] *)
SATBody := Hold[{a (Cos[v] Cos[W] - Cos[i] Sin[v] Sin[W]),
a (Cos[i] Cos[W] Sin[v] + Cos[v] Sin[W]), a Sin[i] Sin[v]}]
SATCompiled = Function[body,
Compile[{{a, _Real}, {i, _Real}, {W, _Real}, {v, _Real}}, body,
CompilationOptions -> {"InlineCompiledFunctions" -> True},
CompilationTarget -> "C"], {HoldAll}] @@ SATBody;
SATUncompiled = Function[body, Function @@ Hold[{a, i, W, v}, body], {HoldAll}] @@ SATBody;
SAT[a_, i_, W_, v_] := If[Apply[And, NumericQ /@ {a, i, W, v}], (* or some other test *)
SATCompiled[a, i, W, v],
SATUncompiled[a, i, W, v]]
I believe that what you are doing is fine and that the Temporary
attributes may be ignored. Symbols created by Module
bear this by default but it should not affect the definitions you create.
Using Block
in place of Module
will clean up the definitions somewhat, but understand what it does before applying it blindly.
Block[{code, a, v, i, W},
code = {a (Cos[v] Cos[W] - Cos[i] Sin[v] Sin[W]),
a (Cos[i] Cos[W] Sin[v] + Cos[v] Sin[W]), a Sin[i] Sin[v]};
SATFast =
Compile[{{a, _Real}, {i, _Real}, {W, _Real}, {v, _Real}}, #,
CompilationOptions -> {"InlineCompiledFunctions" -> True}] &[code];
(SAT[a_?NumericQ, i_?NumericQ, W_?NumericQ, v_?NumericQ] := #[a, i, W, v]) &[
SATFast];
SAT[a_, i_, W_, v_] = code;
];
FullDefinition[SAT]
SAT[a_?NumericQ, i_?NumericQ, W_?NumericQ, v_?NumericQ] := CompiledFunction[Argument count : 4 Argument types : {_Real, _Real, _Real, _Real}][ a, i, W, v] SAT[a_, i_, W_, v_] = {a (Cos[v] Cos[W] - Cos[i] Sin[v] Sin[W]), a (Cos[i] Cos[W] Sin[v] + Cos[v] Sin[W]), a Sin[i] Sin[v]} Attributes[Compile`$4] = {Temporary} Attributes[Compile`$2] = {Temporary} Attributes[Compile`$5] = {Temporary} Attributes[Compile`$1] = {Temporary} Attributes[Compile`$6] = {Temporary}
Possibly of interest:
- How to make a function like Set, but with a Block construct for the pattern names
- Expressions containing globally undefined symbols inside a function where they are defined