What did I do before?
I seem not to be able to understand MMA's evaluation scheme. I read some posts like Preventing Evaluation or a MathGroup post where the topics of evaluation prevention are discussed. Unfortunately, I am not able to fully understand it and use it for my specific purpose. Direct help (or hints to other useful posts) are appreciated.
What's the problem?
I use a quite complicated (and messy) function generate
to generate further functions. This function could output
2 ev[c, k, kF, LatticeSize]
for example. The evaluation to find the new function is costly and I don't want to repeat it but afterwards directly work with the above evaluation result, so I use (notice the Set
notation instead of SetDelayed
)
(* "…" symbolize parameters to generate that are not of importance here for understanding the problem. *)
fun[c_,k_] = generate[…]
Now it is possible to evaluate fun[5,6,1.5,4]
for example and get a result. As soon as I define ev
to be a compiled function (performance is of interest for me), the generate
function tries to evaluate ev
directly. How can this be prevented and instead fun
be made a function that is directly dependent on the compiled (and not evaluated function) ev
?
Bare minimum code
generate[] := 2 ev[c, k, kF, LatticeSize];
ev = Compile[{{i, _Integer}, {j, _Integer}, {kF, _Real},{LatticeSize, _Integer}}, If[i == j, kF/\[Pi], With[{dist = Min[Abs[i - j], LatticeSize - Abs[i - j]]}, 1/\[Pi]*Sin[kF dist]/dist]], RuntimeAttributes -> {Listable}, Parallelization -> True, RuntimeOptions -> "Speed", CompilationTarget -> "C"];
Evaluation of
fun[c_, k_, kF_, LatticeSize_] = generate[]
should show the problem now.
ev
while you definefun
?Block[{ev}, fun[...] = generate[]]
. Thefun
definition would not contain the compiled functions in this case, only theev
symbol. This should not be a problem for as long as you don't change the value ofev
. $\endgroup$