MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: multiple outputs from compiled function

  • To: mathgroup at smc.vnet.net
  • Subject: [mg114698] Re: multiple outputs from compiled function
  • From: Oliver Ruebenkoenig <ruebenko at wolfram.com>
  • Date: Mon, 13 Dec 2010 03:53:24 -0500 (EST)

On Thu, 2 Dec 2010, Daniel Lichtblau wrote:

> Eric Michielssen wrote:
>> Thanks for the suggestion.
>>
>> I was thinking more about a routine that populates a huge sparse matrix, say
>> for finite element analysis. SparseArray does not work within Compile, and
>> that's understandable.
>>
>> So the next best thing would be to have a compiled function generate a long
>> list of positions ( pos = {pos1,pos2,pos3...} with posi = {n1,n2} ) and a
>> list of values ( val = {val1,val2,val3,...} ), and then construct the
>> SparseArray externally to a compiled function.
>>
>> But how do I get my compiled function to return both pos and val? Upon
>> reaching Return[{pos,val}], Mathematica reverts to the noncompiled function,
>> in essence starting over from scratch. (I can only think of a few not so
>> elegant solutions, none of which would apply in situations more complex than
>> the above).
>>
>> Eric
>
> Seems weird, but you might just do the setting via external variable(s).
> Here is a brief example. Notice that the list 'll' is not defined within
> Compile, but it is used in a Part assignment therein.
>
> In[1]:= ll = {2., 3., 4.};
>
> In[2]:= c = Compile[{{x}, {y}}, ll[[1]] = x; y];
>
> In[3]:= c[4.5, 5.6]
> Out[3]= 5.6
>
> In[4]:= ll
> Out[4]= {4.5, 3., 4.}
>
> Daniel Lichtblau
> Wolfram Research
>
>

To be quite honest I pretty much completely missed the point and 
implications of Daniel's post and only "got it" when I received another 
email from a colleague. So I thought I share what I leaned perhaps this is 
useful to others too.

cf = Compile[{{n, _Integer}, {m, _Integer}},
 	Module[
 	{cpos = RandomSample[Range[n], m]},
 	Set[pos, cpos];
 	RandomReal[1, Length[cpos]]
 	]
];

The above compiled function computes some function and stores the result 
in cpos. Then pos - which is a variable not in the Module scope - is set 
to cpos and some other result is returned from the compiled function.

Wrapping the compiled function in, say, a Block

{valres, posres} = Block[{pos}, {cf[10, 5], pos}]

allows for two multiple values to be returned.

Map[Developer`PackedArrayQ, %]

if we look at this compiled function

<< "CompiledFunctionTools`"
CompilePrint[cf]

We see a call to MainEvaluate. Here the main cost is the copy of the cpos 
data and in a big function that would be negligible.

It needs to copy the cpos since you could have something like this:

cf = Compile[{{n, _Integer}, {m, _Integer}},
    Module[{cpos = RandomSample[Range[n], m]},
     Set[pos, cpos];
     cpos[[1]] = 1;
     RandomReal[1, Length[cpos]]]];

This is mechanism that allows for multiple values to be returned from a 
compiled function.

Hope this helps,
Oliver




  • Prev by Date: Re: Replacement Rule with Sqrt in denominator. Also Bug in Series
  • Next by Date: Re: LessEqual vs Inequality, was ..Re: Replacement Rule with Sqrt in denominator
  • Previous by thread: Re: multiple outputs from compiled function
  • Next by thread: Re: SelectionMove[] busted with InputField and DockedCells?