5
$\begingroup$

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?

$\endgroup$
  • 2
    $\begingroup$ Could you please elaborate more on what you are trying to do? Show an example of the function you want to compile, and the options you want to change. $\endgroup$ – rhermans Oct 20 '14 at 17:05
  • $\begingroup$ @rhermans please check the edit. $\endgroup$ – An old man in the sea. Oct 20 '14 at 18:12
  • $\begingroup$ @m_goldberg is this question still not clear? $\endgroup$ – An old man in the sea. Oct 20 '14 at 21:52
  • 1
    $\begingroup$ +1 and a reopen for your update. This is the kind of additional thought and detail required for a good question. $\endgroup$ – Mr.Wizard Oct 21 '14 at 1:33
  • $\begingroup$ @Mr.Wizard Thanks ;) $\endgroup$ – An old man in the sea. Oct 21 '14 at 10:29
4
$\begingroup$

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.

| improve this answer | |
$\endgroup$
  • $\begingroup$ 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. $\endgroup$ – An old man in the sea. Oct 21 '14 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.