]> Creatis software - CreaPhase.git/blob - octave_packages/m/general/nthargout.m
update packages
[CreaPhase.git] / octave_packages / m / general / nthargout.m
1 ## Copyright (C) 2012 Jordi GutiĆ©rrez Hermoso
2 ##
3 ## This file is part of Octave.
4 ##
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
9 ##
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 ## General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING.  If not, see
17 ## <http://www.gnu.org/licenses/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn  {Function File} {} nthargout (@var{n}, @var{func}, @dots{})
21 ## @deftypefnx {Function File} {} nthargout (@var{n}, @var{ntot}, @var{func}, @dots{})
22 ## Return the @var{n}th output argument of function given by the
23 ## function handle or string @var{func}.  Any arguments after @var{func}
24 ## are passed to @var{func}.  The total number of arguments to call
25 ## @var{func} with can be passed in @var{ntot}; by default @var{ntot}
26 ## is @var{n}.  The input @var{n} can also be a vector of indices of the
27 ## output, in which case the output will be a cell array of the
28 ## requested output arguments.
29 ##
30 ## The intended use @code{nthargout} is to avoid intermediate variables.
31 ## For example, when finding the indices of the maximum entry of a
32 ## matrix, the following two compositions of nthargout
33 ##
34 ## @example
35 ## @group
36 ## @var{m} = magic (5);
37 ## cell2mat (nthargout ([1, 2], @@ind2sub, size(@var{m}),
38 ##                      nthargout (2, @@max, @var{m}(:))))
39 ## @result{} 5   3
40 ## @end group
41 ## @end example
42 ##
43 ## @noindent
44 ## are completely equivalent to the following lines:
45 ##
46 ## @example
47 ## @group
48 ## @var{m} = magic(5);
49 ## [~, idx] = max (@var{M}(:));
50 ## [i, j] = ind2sub (size (@var{m}), idx);
51 ## [i, j]
52 ## @result{} 5   3
53 ## @end group
54 ## @end example
55 ##
56 ## It can also be helpful to have all output arguments in a single cell
57 ## in the following manner:
58 ##
59 ## @example
60 ## @var{USV} = nthargout ([1:3], @@svd, hilb (5));
61 ## @end example
62 ##
63 ## @seealso{nargin, nargout, varargin, varargout, isargout}
64 ## @end deftypefn
65
66 ## Author: Jordi GutiĆ©rrez Hermoso
67
68 function out = nthargout (n, varargin)
69   if (nargin < 2)
70     print_usage ();
71   endif
72
73   if (isa (varargin{1}, "function_handle") || ischar (varargin{1}))
74     ntot = max (n(:));
75     func = varargin{1};
76     args = varargin(2:end);
77   elseif (isnumeric (varargin{1})
78           && (isa (varargin{2}, "function_handle") || ischar (varargin{2})))
79     ntot = varargin{1};
80     func = varargin{2};
81     args = varargin(3:end);
82   else
83     print_usage ();
84   endif
85
86   if (any (n != fix (n))  || ntot != fix (ntot) || any (n <= 0) || ntot <= 0)
87     error ("nthargout: N and NTOT must consist of positive integers")
88   endif
89
90   outargs = cell (1, ntot);
91
92   try
93     [outargs{:}] = feval (func, args{:});
94     if (numel (n) > 1)
95       out = outargs(n);
96     else
97       out = outargs{n};
98     endif
99   catch
100     err = lasterr ();
101     if (strfind ("some elements undefined in return list", err))
102       error ("nthargout: Too many output arguments: %d", ntot);
103     else
104       error (err);
105     endif
106   end_try_catch
107
108 endfunction
109
110 %!shared m
111 %! m = magic (5);
112 %!assert (nthargout ([1, 2], @ind2sub, size(m), nthargout (2, @max, m(:))), {5,3}) 
113 %!assert (nthargout (3, @find, m(m>20)), [23, 24, 25, 21, 22]')