How to force MATLAB to return all values in a nested function call?

假如想象 提交于 2019-11-28 06:11:58

问题


I find it impossible to write MATLAB code without creating a huge number of superfluous, single-use variables.

For example, suppose function foo returns three column vectors of exactly the same size. Say:

function [a, b, c] = foo(n)
    a = rand(n, 1);
    b = rand(n, 1);
    c = rand(n, 1);
end

Now, suppose that bar is a function that expect as imput a cell array of size (1, 3).

function result = bar(triplet)
    [x, y, z] = triplet{:};
    result = x + y + z;
end

If I want to pass the results of foo(5), I can do it by creating three otherwise-useless variables:

[x, y, z] = foo(5);
result = bar({x, y, z});

Is there some function baz that would allow me to replace the two lines above with

result = bar(baz(foo(5)));

?

NB: the functions foo and bar above are meant only as examples. They're supposed to represent functions over which I have no control. IOW, modifying them is not an option.


回答1:


Not possible. baz in baz(foo(5)) will only take the first output of foo, the other two would be ignored. The plain two-line variant is not that awkward. And this is not a common situation. You don't generally work with cell arrays where normal numerical arrays would do.

You could of course just write your own wrapper for foo that returns whatever you need (i.e. containing similar two lines), in case you need to use it frequently.




回答2:


You can replace the three variables by a cell array using a comma-separated list:

vars = cell(1,3);     % initiallize cell array with as many elements as outputs of foo
[vars{:}] = foo(5);   % comma-separated list: each cell acts as a variable that 
                      % receives an output of foo
result = bar(vars);



回答3:


As nirvana-msu said, it is not possible to do the task without creating temporary variables. But it is possible to handle it within a function and even with varargin and varargout. Inspired by this answer on my question, you can define and use the following function:

function varargout = redirect(F1, F2, count, list, varargin)
    output = cell(1, count);
    [output{:}] = F2(varargin{:});
    varargout = cell(1, max(nargout, 1));
    [varargout{:}] = F1(output(list));
end

For instance, in your example you can write result = redirect(@bar, @foo, 3, [1:3], 5);




回答4:


The issue is you are converting the cell triplet{} into an array[], so a conversion is the method you want. Although this method will perform the inverse transformation, I know of no method that will perform the transformation you want, likely due to the relative complexity of the cell data structure. You may have some luck further digging into the API.

EDIT: EBH kindly pointed out this method, which does what you are looking for.

EDIT2: The above method will not perform the action OP asked for. Leaving this up because the API often has great solutions that are hidden by bad names.



来源:https://stackoverflow.com/questions/38213814/how-to-force-matlab-to-return-all-values-in-a-nested-function-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!