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}

Tags:

Compile