MathGroup Archive 2010

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

Search the Archive

Re: multiple outputs from compiled function

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}},
 	{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`"

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,

  • 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?