how to return two results by one output when using arrayfun()?
Show older comments
f=@(X) fun1(x);
data=arrayfun(f,xgroup);
about funtion 'fun1', now shall I return two result into the 'data' for one element of xgroup;
funtion re=fun1(x)
....
out1=x^2;
out2=x^3;
re=[out1 out2];
end
When I do like above, Matlab cant accept it; so is there some method to return several results by one 'var'?
7 Comments
vx2008's "Answer" moved here (note to vx2008: please use the comment fields, not the answers):
Thank you for your guidings;
yes, you have give me the solution, and my request is the type as you show:
result = arrayfun(@fun1, 1:5, 'UniformOutput', false)
but there is a little bug here: what if 'output3' is string? like this: ' output3= 'test' '; I know we can make code as below:
function re = fun1(x) %function is designed to work on scalars only
output1=x^2;
output2=x^3;
output3='test'
re = {output1,output2,output3};
end
But if that, how shall I get matrix Data=[output1,output2] and Str={output3} from the 'result' of 'arraryfun'? I mean use 'cell2mat' function or related function to do this rather than one by one.
And I also know we can resolve this problem like this:
[re1, re2,re3] = arrayfun(@fun1, 1:5) and alse 3 outputs in 'fun1';
the reason why I don;t select this type is that I will modify the outputs' number in the future, and it will be more convenient if I select the other type.
@vx2008: Don't make code more complicated than it needs to be.
You are avoiding using the simplest solution ( multiple outputs) and trying to mock-up some syntax that allows you to create arbitrary outputs and then you expect them to be magically combined using some simple tool. There is a simple tool: multiple outputs. Why do you not know what the outputs are? You write the code, you know what the outputs are.
"there is a little bug here" The bug is that you want to merge data of different types into one cell array, and then imagine that it will be simple to separate them again. There are two cases to consider:
- if you know what order the data are in within the cell array then you might as well just use multiple outputs (see examples below).
- if the data types are not known when you write the code then there is no simple solution: you would need to identify them within the cell array. Considerreturning one structure instead (see my next comment).
You can easily collect multiple outputs into one cell array. Here is a simple function with two outputs, which when it is called are collected into one cell array:
function [sq,cu] = myFunTwo(x) % two outputs
sq = x^2;
cu = x^3;
end
and call it like this:
>> [X{1:2}] = arrayfun(@myFunTwo,1:3);
>> data = vertcat(X{:})
data =
1 4 9
1 8 27
You see, by using multiple outputs we can:
- make the function simpler
- make the arrayfun call simpler
- put the outputs easily into one cell array (which was also easy to convert to numeric).
You can even extend this to work with more outputs, of mixed data types:
function [sq,cu,st] = myFunThree(x) % three outputs
sq = x^2;
cu = x^3;
st = {num2str(cu)}; % string in a cell!
end
and called:
>> [X{1:2},Str] = arrayfun(@myFunThree,1:3);
>> Str{:} % string in cell array
ans = 1
ans = 8
ans = 27
>> data = vertcat(X{:})
data =
1 4 9
1 8 27
See how easy it is to combine when we use multiple outputs.
vx2008
on 1 Feb 2016
function out = myFunStruct(x) % one structure output
out.square = x^2;
out.cube = x^3;
out.string = num2str(out.cube);
end
and call it like this:
>> X = arrayfun(@myFunStruct,1:3)
X =
1x3 struct array containing the fields:
square
cube
string
>> [X.cube]
ans =
1 8 27
>> {X.string}
ans = '1' '8' '27'
This may be the simplest solution for you: you can choose as many fields as you wish, and the arrayfun call does not change. However the task of identifying those fields remains for you to solve!
Note that there are neat ways of accessing the structure data:
vx2008
on 1 Feb 2016
Stephen23
on 1 Feb 2016
My aim is to show you some good choices, but because I do not know the rest of your data processing I can't advise on which solution is best for your situation: it depends on how you are generating and handling this data.
Pick the solution that makes the most sense to you, or that you find easiest to code. (Writing code that makes sense saves more time than trying to write slightly faster code that is harder to understand and causes problems...)
For "large" data separate outputs may be faster, but the only way to check is to try both solutions and time them.
vx2008
on 1 Feb 2016
Accepted Answer
More Answers (1)
Guillaume
on 1 Feb 2016
It's not clear what sort of output you are looking for out of arrayfun. You have two options:
- Use a single output function that outputs a vector, as in your example:
function re = fun1(x) %function is designed to work on scalars only
re = [x^2 , x^3]
end
If you use this function in the arrayfun call the output is non-scalar and thus you need to tell arrayfun. As a result, arrayfun will pack the outputs in a cell array:
result = arrayfun(@fun1, 1:5, 'UniformOutput', false) %create a cell array
If you want, you can then convert the cell array into a 2 column matrix:
result = vertcat(result{:})
- Second option: Use a two outputs function and therefore have two output arrays out of arrayfun:
function [out1, out2] = fun2(x)
out1 = x^2;
out2 = x^3;
end
[re1, re2] = arrayfun(@fun1, 1:5)
You can of course concatenate the output directly into a 2d matrix:
[result(1, :), result(2, :)] = arrayfun(@fun1, 1:5)
Finally, I'll note that in this particular example, arrayfun is completely unnecessary:
result = [x.^2; x.^3] %would do the same
Categories
Find more on Structures in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!