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

I am unable to write MATLAB code without creating a huge number of extra one-time variables.

For example, suppose the 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 bar is a function that expects an array of cells of size (1, 3) as imput.

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

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

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

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

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

?

NB: the functions foo and bar above are provided as examples only. They should represent functions that I do not control. IOW, changing them is not an option.

+1
source share
4 answers

Impossible. baz in baz(foo(5)) will only accept the first output of foo , the other two will be ignored. A simple two-line version is not that inconvenient. And this is not an ordinary situation. Usually you don’t work with cell arrays where you would do regular numeric arrays.

You could just write your own wrapper for foo , which returns everything you need (i.e. contains two similar lines) if you need to use it often.

+2
source

You can replace three variables with an array of cells 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
source

As nirvana-msu said: it is impossible to complete a task without creating temporary variables. But it can be processed inside a function and even with varargin and varargout . Inspired by this answer to 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 example, in your example, you can write result = redirect(@bar, @foo, 3, [1:3], 5);

+1
source

The problem is that you are converting the triplet of cell {} into an array [], so conversion is the method you want. Although this method will perform the inverse transform, I do not know of any method that will perform the required transform, probably due to the relative complexity of the cell's data structure. You may be able to go even deeper into the API.

EDIT: EBH has kindly noted this method , which does what you are looking for.

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

0
source

Source: https://habr.com/ru/post/1259443/


All Articles