# Compile a precomputed list-type expression

I precompute an expression which takes pretty long to evaluate (i.e. for my real problem tmp[2] takes quite long) and I want to see if runtime can be improved using Compile. Consider expr below which can in my case either be a vector or a matrix. It is then "transformed" into a function like tmp[t]. Using Compile I ran into the following issue:

ClearAll[tmp, fun, fun2, fun3, expr];
expr = {Sin[t], Cos[t]};
tmp[t_] = expr;
fun = Compile[{{t, _Real}}, tmp[t]];
fun2 = Compile[{{t, _Real}}, expr];
fun3 = Compile[{{t, _Real}}, {Sin[t], Cos[t]}];


Now evaluating the three variants yields

Option 1:

fun[2.]


CompiledFunction::cfex: Could not complete external evaluation at instruction 1; proceeding with uncompiled evaluation.

(* {0.909297, -0.416147} *)


Option 2:

fun2[2.]


CompiledFunction::cfte: Compiled expression {Sin[t],Cos[t]} should be a rank 1 tensor of machine-size real numbers. CompiledFunction::cfex: Could not complete external evaluation at instruction 1; proceeding with uncompiled evaluation.

(* {Sin[t], Cos[t]} *)


Option 3:

fun3[2.]
(* {0.909297, -0.416147} *)


Considering that

ClearAll[fun4,tmp2];
tmp2[t_] = expr[[1]];
fun4 = Compile[{{t, _Real}}, tmp2[t]];
fun4[2.]
(* 0.909297 *)


Concluding, I could apply Compile to all elements of my list and then merge the compiled functions into a single function, but that seems rather complicated and possibly what I need, i.e. something along the lines of fun, is easily realized if one knows how.

So the question is: Can anyone please let me know how to run Compile on a list that is stored in some precomputed expression?

## Edit & Update

I have just found something related but I cannot get a solution out of it. The issue might be related to packed vs unpacked arrays, at least this is what I guess from the linked question.

Needs["CompiledFunctionTools"];
CompilePrint[fun]
CompilePrint[fun3]


shows that fun has a call to MainEvaluate whilst fun3 does not:

(* output for fun *)
1 argument
2 Real registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}

R0 = A1
Result = R1

1   R1 = MainEvaluate[ Hold[tmp][ R0]]
2   Return

(* output for fun3 *)
1 argument
3 Real registers
1 Tensor register
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}

R0 = A1
Result = T(R1)0

1   R1 = Sin[ R0]
2   R2 = Cos[ R0]
3   T(R1)0 = {R1, R2}
4   Return

• You need With[] for injecting code: fun4 = With[{e = expr}, Compile[{{t, _Real}}, e]]. Or, some trickery with Hold[]/ReleaseHold[]: fun5 = ReleaseHold[Hold[Compile][{{t, _Real}}, expr]]. – J. M.'s technical difficulties Mar 19 '18 at 17:13
• @J.M. Thank you very much for this suggestion! If you wish you can turn it into an answer and I will accept. Unfortunately I now run into another error related to a numerical error when evaluating the CompiledFunction` of my actual problem. Is it better to rewrite the question (shorten its current content) and extend it by the real expression I am working with, or should I rather open a second question purely focussing on that specific issue? – Lukas Mar 19 '18 at 17:32
• I am pretty sure this is a dupe, but I am unable to recall where the original is. Your new error ought to be a separate question, I think. – J. M.'s technical difficulties Mar 19 '18 at 17:35