I'm about to build a package that will provide lots of simple functions. I want these functions to run as fast as possible when evaluating numerically but still provide symbolic results when needed. To cut down on coding errors I only want to define the core function once. I have a first cut at something that seems to work but when I look at the definition with FullDefinition[]
I see things that I do not expect.
Here is a definition of one of the functions:
Module[{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 = With[
{
Ccode = code
},
Compile[{{a, _Real}, {i, _Real}, {W, _Real}, {v, _Real}},
Ccode
,
CompilationOptions -> {"InlineCompiledFunctions" -> True},
CompilationTarget -> "C"
]
];
With[{
fun = SATFast
},
(*Define the special case first!*)
SAT[av_?NumericQ, iv_?NumericQ, Wv_?NumericQ, vv_?NumericQ] :=
fun[av, iv, Wv, vv];
SAT[av_, iv_, Wv_, vv_] :=
Evaluate[code /. {a -> av, i -> iv, W -> Wv, v -> vv}];
]
];
This will ultimately be in a package where I will have a usage
statement for the function SAT
but not for the function SATFast
. I expect to be able to use SATFast
inside of other functions within the package.
I'm concerned with the output of FullDefinition[SAT]
.
The first line of output, which was displayed as a CompiledFunction[]
object in Mathematica but shows more detail here is as follows:
SAT[av$_?NumericQ, iv$_?NumericQ, Wv$_?NumericQ, vv$_?NumericQ] :=
CompiledFunction[{10, 11.1, 5468}, {
Blank[Real],
Blank[Real],
Blank[Real],
Blank[Real]}, {{3, 0, 0}, {3, 0, 1}, {3, 0, 2}, {3, 0, 3}, {3, 1,
0}}, {}, {0, 0, 13, 0,
1}, {{40, 2, 3, 0, 1, 3, 0, 4}, {40, 2, 3, 0, 2, 3, 0, 5}, {40, 1,
3, 0, 3, 3, 0, 6}, {40, 2, 3, 0, 3, 3, 0, 7}, {40, 1, 3, 0, 2, 3,
0, 8}, {16, 7, 5, 9}, {16, 4, 6, 8, 10}, {19, 10, 11}, {13, 9, 11,
9}, {16, 0, 9, 11}, {16, 4, 5, 6, 9}, {16, 7, 8, 10}, {13, 9, 10,
9}, {16, 0, 9, 10}, {40, 1, 3, 0, 1, 3, 0, 9}, {16, 0, 9, 6,
12}, {34, 1, 3, 11, 10, 12, 3, 0}, {1}},
Function[{a$5296, i$5296, W$5296, v$5296},
Block[{Compile`$9, Compile`$7, Compile`$10, Compile`$3, Compile`$11},
Compile`$9 = Cos[i$5296]; Compile`$7 = Cos[
W$5296]; Compile`$10 = Sin[v$5296]; Compile`$3 = Cos[
v$5296]; Compile`$11 = Sin[W$5296]; {
a$5296 (Compile`$3 Compile`$7 - Compile`$9 Compile`$10 Compile`$\
11), a$5296 (
Compile`$9 Compile`$7 Compile`$10 + Compile`$3 Compile`$11),
a$5296 Sin[i$5296] Compile`$10}]], Evaluate,
LibraryFunction[
"/home/paulb/.Mathematica/ApplicationData/CCompilerDriver/\
BuildFolder/trail-19983/compiledFunction1.so",
"compiledFunction1", {{Real, 0, "Constant"}, {
Real, 0, "Constant"}, {Real, 0, "Constant"}, {
Real, 0, "Constant"}}, {Real, 1}]][av$, iv$, Wv$, vv$]
Line two:
SAT[av$_, iv$_, Wv$_,
vv$_] := {av$ (Cos[vv$] Cos[Wv$] - Cos[iv$] Sin[vv$] Sin[Wv$]),
av$ (Cos[iv$] Cos[Wv$] Sin[vv$] + Cos[vv$] Sin[Wv$]),
av$ Sin[iv$] Sin[vv$]}
So far these two lines are what I would expect but then I also get the following:
Attributes[av$] = {Temporary}
Attributes[iv$] = {Temporary}
Attributes[Wv$] = {Temporary}
Attributes[vv$] = {Temporary}
Attributes[a$5296] = {Temporary}
Attributes[i$5296] = {Temporary}
Attributes[W$5296] = {Temporary}
Attributes[v$5296] = {Temporary}
Attributes[Compile`$9] = {Temporary}
Attributes[Compile`$7] = {Temporary}
Attributes[Compile`$10] = {Temporary}
Attributes[Compile`$3] = {Temporary}
Attributes[Compile`$11] = {Temporary}
Am I not scoping my variables correctly? Is there a better way to scope the dummy variables in the symbolic definition?