How to force Compile to return multiple results?
What about making the result uniform inside Compile and constructing things back afterwards? Like
cFunc = Compile[
{{a, _Integer, 1}},
Join @@ {a, {a . a}}];
cFunc[{1, 3}]
Function[z, {Most[z],
Last[z]}][%]
which has the nice feature of not calling MainEvaluate:
Needs["CompiledFunctionTools`"]; cFunc // CompilePrint
(*
==>
1 argument
2 Integer registers
3 Tensor registers
Underflow checking off
Overflow checking off
Integer overflow checking on
RuntimeAttributes -> {}
T(I1)0 = A1
I0 = 4
Result = T(I1)2
1 I1 = DotVV[ T(I1)0, T(I1)0, I0]]
2 T(I1)1 ={ I1 }
3 T(I1)2 = Join[ T(I1)0, T(I1)1]]
4 Return
*)
You can use a technique like this:
cf = Compile[{{n, _Integer}, {m, _Integer}},
Module[{cpos = RandomSample[Range[n], m]},
Set[pos, cpos];
RandomReal[1, Length[cpos]]]];
{valres, posres} = Block[{pos}, {cf[10, 5], pos}]
The set works on a variable which is scoped with Block. Since this is done only once, the call to MainEvaluate is not a problem.
A couple of ideas:
cfun = Compile[{{a, _Integer, 1}}, x[1] = a; x[2] = a.a;]
fun[a_?VectorQ] :=
Block[{x},
cfun[a];
{x[1], x[2]}
]
fun[{1,2,3,4,5}]
{{1, 2, 3, 4, 5}, 55}
cf2 = Compile[{{a, _Integer, 1}}, Sow[a]; Sow[a.a];];
Reap[cf2@{1, 2, 3, 4, 5}][[2, 1]]
{{1, 2, 3, 4, 5}, 55}