5

Is it possible to compile while changing the value of the arguments the function receives, instead of just creating new variables, and then returning those new variables,i.e., is it possible to pass by reference? How do I do this?

As an example:

cf=Compile[{{mat1,_Real,3},{mat2,_Real,3}},

mat1=mat1+mat2;
mat2=mat2*2;

]

where mat1 and mat2 are matrices of dimension $3\times N$.

When trying to compile the function cf I get the error

Compile::argset: The assignment to mat1 is illegal; it is not valid to assign a value to an argument.

So, my question is how can I bypass this, and use pass by reference instead of pass by value?

An old man in the sea.
  • 2,527
  • 1
  • 18
  • 26

1 Answers1

4

As far as I understand the concept there is no true pass-by-reference in Mathematica. Attempting to make assignments to arguments is in fact a common mistake which I addressed in this answer: Attempting to make an assignment to the argument of a function. As described there one needs a Hold attribute for in-place modification of definitions, e.g.:

SetAttributes[foo, HoldFirst]
foo[bar_, new_] := bar = {bar, new};

x = {1};
foo[x, 2];

x
{{1}, 2}

This requires passing a Symbol name which is not a type that is supported by Compile.
One can nevertheless make assignments to Symbols (through a callback to the main evaluator):

cf = Compile[{{mat1, _Real, 3}}, x = mat1; 1];

cf[{{{2}, {8}}}];

x
{{{2.}, {8.}}}

Since this is a main evaluator callback the assignment function exists verbatim in cf:

Cases[cf, _Function, -1, 1]
{Function[{mat1}, x = mat1]}

This means that you can actually replace that Symbol with a different one, e.g.:

(cf /. HoldPattern[x] :> q)[{{{4, 5, 6}}}]

q

x
{{{4., 5., 6.}}}

{{{2.}, {8.}}}

Note that x was not modified. This illustrates that you can write hybrid functions that are partially compiled and yet have assignments to passed-in Symbols. Whether or not this prove to be useful in practice remains to be seen. If this does seem to be what you are looking for I can develop this further.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • I think the example you gave, with the callback to the main evaluator is enough for my case. The rest, I didn't seem to understand :/ I'll have to study what it means as soon as I get some free time. – An old man in the sea. Oct 21 '14 at 20:46