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 a
s and will miss the b
s (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 b
s? i.e. giving a behavior analogous to a definition of foo
like
b = foo(c)
i.e.^2, wasting the a
s.
Moreover, is it possible to (efficiently) catch both a
and b
in a unique cellfun
call?
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.
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).
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
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}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With