Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matlab: defining a function handle catching second returned value of a function

Say that I have a function foo defined as

   [a b] = foo(c ).

If I consider a function handle

 f = @(c)foo(c)

to be used e.g. in a cellfun call, what I get is an f behaving equivalently to a foo defined like

  a = foo(c)

i.e., the returned value b gets lost.

Therefore, when such an f is put in a cellfun call, the output cell will have just the as and will miss the bs (which I currently care about). Visually

    cellfun(f,input)

  [a(input{1})]           ?
  [a(input{2})]           ?
     ....            b gets killed along the way

Question: how to define a function handle to foo which catches just the bs? i.e. giving a behavior analogous to a definition of foo like

  b = foo(c)

i.e.^2, wasting the as.

Moreover, is it possible to (efficiently) catch both a and b in a unique cellfun call?

like image 514
Acorbe Avatar asked Nov 21 '12 09:11

Acorbe


People also ask

How do you define a function handle in MATLAB?

Function handles can represent either named or anonymous functions. To create a function handle, use the @ operator. For example, create a handle to an anonymous function that evaluates the expression x2 – y2: f = @(x,y) (x. ^2 - y.

How do you return a function handle in MATLAB?

handle = @functionname returns a handle to the specified MATLAB function. A function handle is a MATLAB value that provides a means of calling a function indirectly. You can pass function handles in calls to other functions (often called function functions).


2 Answers

From the documentation of cellfun:

[A1,...,Am] = cellfun(func,C1,...,Cn) calls the function specified by function handle func and passes elements from cell arrays C1,...,Cn, where n is the number of inputs to function func. Output arrays A1,...,Am, where m is the number of outputs from function func, contain the combined outputs from the function calls.

So yes, cellfun can use a multi-output function and in this case it simply returns a number of outputs. If you want to use the second one only, you can use ~ to ignore the first one. The same goes for multiple outputs of anonymous functions - they will be returned if you specify multiple output arguments. Here is a simple code:

function test
    x{1} = 1;
    x{2} = 2;
    [~, B] = cellfun(@foo, x);
    f=@(c)foo(c);
    [A, B] = f(1);

    function [a b] = foo(x)
        a = x+1;
        b = x+2;
    end
end
like image 51
angainor Avatar answered Oct 28 '22 08:10

angainor


This can be done by using a cell array as the single output of the function, instead of a function with multiple outputs.

Define your function to return a cell array (or create an auxiliary function that calls the original multiple-output function):

function F = foo2(x)
  [a,b,c] = foo(x);
  F = {a, b, c};
end

And then you can create a handle that calls your function and gets only one of the cells from the cell array.

f = @(x) cell(foo2(x)){2} % This selects the second output
g = @(x) cell(foo2(x)){3} % This selects the third output

Which is almost exactly what you were asking for. You could even create a handle that returns the n-th output

f = @(x,n) cell(foo2(x)){n}
like image 25
Francisco Rodríguez Fortuño Avatar answered Oct 28 '22 08:10

Francisco Rodríguez Fortuño