5

Suppose I have a function that gives out unknown number of output arguments (it depends on input,thus change through the loops). How to get all of them?

nargout doesn't help as the function uses varargout (the result is -1)

And of course I can't rewrite the function, otherwise the question wouldn't arise :- )

Noxobar
  • 141
  • 5
  • You know the inputs - are you saying that you nevertheless don't know how many outputs the function returns? Outputs may depend on inputs, but usually there's supposed to be a simple relation between inputs and the number of outputs... for a reasonably well designed function at least. – sebastian Jul 09 '14 at 15:14
  • 1
    Try to assign the output to a single variable. This variable should be a cell array itself if varargout is used. Find out its length. – freude Jul 09 '14 at 15:17
  • Actually I am struggling to find a reasonable situation where you don't know how many outputs are coming. Could you provide an example? – Dennis Jaheruddin Jul 09 '14 at 15:17
  • @sebastian Well, fortunately, the relation is clear: the number of outputs is the length of the function's second argument array... But it means that I need to prepare a receiver cell array beforehand. It can be done in this particular case, but what if?... :-) – Noxobar Jul 09 '14 at 15:27
  • @DennisJaheruddin Easily. The function that solves some differential equation for eigenvalues. With some threshold solution selection. – Noxobar Jul 09 '14 at 15:30
  • The kind of function you describe indeed asks for a solution as suggested by @freude. Put all solutions in a cell and sort them out later. – Dennis Jaheruddin Jul 09 '14 at 15:43
  • @DennisJaheruddin If I was a person writing that function I would definitely do that and no question would have arised – Noxobar Jul 09 '14 at 16:09
  • @Divakar I considered this in the question statement. I'm not writing this function. I'm working with it. If I could change the source code I would use single cell array for output instead the `varargout` to remove all problems – Noxobar Jul 09 '14 at 16:15
  • @Divakar I've said about it about three times allready (see comments bellow). `nargout` works only for fixed arguments. When it sees `varargout` it returns -1 or -n, where n is the number of fixed arguments (see http://www.mathworks.com/help/matlab/ref/nargout.html). – Noxobar Jul 09 '14 at 18:05
  • @Noxobar Sorry my bad there, didn't read through the comments properly. – Divakar Jul 09 '14 at 21:07
  • 1
    Interesting question. I'd have to guess that there's no good general solution to this. I think the number of outputs a function call (as opposed to the function definition) has must be defined *before* the function is evaluated. This is suggested by the help for `nargout`: "Inside the body of a user-defined function, nargout returns the number of output arguments that were used to call the function." (Note that this refers to inside your function that uses `varargout`, not outside it where you're correct that it's not really helpful here.) – horchler Jul 10 '14 at 02:59
  • 2
    @Noxobar IMHO, that is the only proper way to do this. Everyone programming a function that returns a variable and a priori unknown number of outputs ought to be punished. It would simply be a really bad example of how to use the feature of having multiple outputs... – sebastian Jul 10 '14 at 07:58

3 Answers3

7

Well, thanks to all partisipated in discussion. Summing up, it seems the problem has no general solution, because MatLab itself estimates the number of desired outputs before the function call to use inside it. Three cases can be pointed out though:

1) The funcrion doesn't have varargout in definition, thus nOut=nargout(@fcn) returns positive number.

Then nOut is an actual number of outputs and we can use a cell array and a column list trick.

X=cell(1,nOut);
[X{:}]=fcn(inputs);

2) The funcrion has varargout in definition, thus nOut=nargout(@fcn) returns negative number. However some correlation with inputs can be found (like length(varargin)=length(varargout)).

Then we can calculate the resulting nOut from inputs and perform the above column list trick.

3) You know the fcn developer.

Ask him fot assistance. For example to make the function's output to be a cell array.

Noxobar
  • 141
  • 5
3

One of ways I usually use in this case is to store all outputs in a cell array inside the function. Getting the cell array outside the function's body, you might investigate its length and other properties.

freude
  • 3,632
  • 3
  • 32
  • 51
  • I have no access into the function :- ) If I had, no question should have appeared :- ) – Noxobar Jul 09 '14 at 15:09
  • This may help, but it would (of course) require editing the relevant function. – Dennis Jaheruddin Jul 09 '14 at 15:09
  • Try to assign the output to a single variable. This variable should be a cell array itself. Find out its length. – freude Jul 09 '14 at 15:15
  • Suppose the function is `unique` and you dont know that it has 3 output arguments, then how would you deal with it? – Dennis Jaheruddin Jul 09 '14 at 15:18
  • Is varargout used inside the function? If yes, the output is essentially a cell array. – freude Jul 09 '14 at 15:22
  • 1
    @DennisJaheruddin well, if the function has 3 **fixed** arguments (defined as `function [a,b,c]=unique`) then I just call `Nout=nargout(unique)`. But if the function uses `varargout` then Nout always goes -1 (or -n, where n is the number of fixed arguments) @freude no. In all cases the output waits a list like `[X{:}]` where `X=cell(1,Nout)`. But everything doesn't work until I know `Nout` exactly. – Noxobar Jul 09 '14 at 16:00
0

Here is how you could deal with the problem in general. I didn't mention this solution earlier because... it is horrible.

Suppose a function can have 1 or 2 output arguments:

try 
  [a, b] = f(x)
catch
  a = f(x)
end

Of course it is possible to do this for any number of output arguments, but you really don't want to.

Dennis Jaheruddin
  • 21,208
  • 8
  • 66
  • 122