Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anonymous functions calling functions with multiple output forms

Tags:

matlab

I'm trying to define an anonymous function that calls a version of a function that returns multiple outputs.

For example, the function find has two possible output forms:

[row,col] = find(X);

and

[ind] = find(X);

Say I would like to choose the first form inside of an anonymous function.

I have tried 1)

get_columns = @(x) x(2);

and 2)

get_columns = @(x,y) y;

But when I call:

get_columns(find(x))

The first version of get_columns thinks I am calling find as [ind] = find(X) and not as [row,col] = find(X);, while the second one complains with "Not enough input arguments".

Is there a way to trigger a specific output form of a function inside an anonymous function?

like image 333
Amelio Vazquez-Reina Avatar asked Oct 27 '11 19:10

Amelio Vazquez-Reina


2 Answers

Directly, no. Unfortunately, there are a number of features which are inaccessible via anonymous functions, and accessing multiple output arguments is one of them. (The other one I frequently find is that you cannot define an if statement inside an anonymous function. This appears to be a limitation of Matlab syntax more than anything else.

However, a pretty simple helper function can make this possible.

function varargout = get_outputs(fn, ixsOutputs)
output_cell = cell(1,max(ixsOutputs));
[output_cell{:}] = (fn());
varargout = output_cell(ixsOutputs);

This function takes a function handle plus an array of output indexes, and returns the indexed outputs.

If you create this file (hopefully better commented) and put it on your path, then you can access the second output of the find function as by defining the following function

find_2nd = @(x)get_outputs(@()find(x),2)

And now you can find the find the indexes of an array which equal 1 as

>> find_2nd([4 3 2 1]==1)
ans =
    4

And now you should be able to access alternative output arguments at-will from within anonymous functions.

like image 148
Pursuit Avatar answered Sep 21 '22 23:09

Pursuit


This get_outputs function above could be widely useful for brief anonymous functions. Very nice.

Also, regarding the comment that an "if" can't be used in MATLAB, this is only partially true. Identical behavior can easily be implemented anonymously. For instance, here's an anonymous if:

anonymous_if = @(varargin) varargin{2*find([varargin{1:2:end}], 1, 'first')}();

Use:

out = anonymous_if(condition1, action1, condition2, action2, ...);

The action corresponding to the first true condition is executed. For instance, this prints 'hello'.

anonymous_if(false, @() disp('hi'), ... % if false, print 'hi'
             true,  @() disp('hello'))  % else if true, print 'hello'

Granted, it's a bit complicated at first sight, but I keep something like this on my path so I can use an "if" in an anonymous function. Much more complex anonymous functions can be built in this way.

like image 42
Tucker Avatar answered Sep 18 '22 23:09

Tucker