help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Forcing Variable Outputs


From: John W. Eaton
Subject: Forcing Variable Outputs
Date: Wed, 29 Mar 2006 00:45:32 -0500

On 28-Mar-2006, Bill Denney wrote:

| I have a function that I want to force to have a variable number of output 
| arguements based on its calling function's number of output arguements. 
| In other words, I want to do something like
| 
| function [varargout] = fxn1(varargin)
| 
|    varargout{:} = fxn2(varargin{:});
| 
| endfunction
| 
| and I want fxn2 to see the same number of output arguements that fxn1 
| sees.
| 
| I thought of initializing varargout like
| 
| varargout = cell(1, nargout);
| 
| but that didn't work.  Is there a way to do this?

I think what you want is

  function varargout = fxn1 (varargin)
    varargout = cell (nargout, 1);
    [varargout{:}] = fxn2 (varargin{:});
  endfunction

but this feature of Matlab is not yet implemented in Octave.  The
reason it is not done yet is that decoding the LHS of the assignment

  [varargout{:}] = fxn2 (varargin{:});

must be done before the function on the RHS is called so that nargin
may be set properly when the function is called, and doing that in the
general case is relatively complex and may require partial evaluation
of the expression inside the square brackets on the LHS.  For example,
think about a case like

  [foo(i,j(k),f(x,y,z)).bar{s:t}] = fxn2 (...);

the index expressions used here could be functions with side effects,
etc.  To know precisely how many elements are in the comma-separated
list on the LHS, the expression must be evaluated.  I'm not sure what
is reasonable in a complex case like this, or what Matlab does.  Even
if function calls are not allowed inside an expression like this,
implementing this feature requires a significant change to the way
Octave works because Octave currently evaluates the LHS after the RHS
(all we do is count the number of expressions in the list inside the
square brackets on the LHS, and set nargout to that number).

Note that in Octave it is possible to write

  function varargout = f1 (varargin)
    varargout = cell (nargout, 1);
    [varargout{:}] = f2 (varargin{:});
  endfunction
  function varargout = f2 (varargin)
    nargin
    nargout
    varargout = varargin;
  endfunction

and things appear to work for a call like

  octave:8> [a,b,c] = f1 (1,2,3)
  ans = 3
  ans = 1
  a = 1
  b = 1
  c = 1

except that nargout is wrong in the call to f2.  It should be 3
instead of 1.

But maybe it would be relatively simple to correctly handle simple
cases like the one in your example above, and implementing that might
get 90% of the uses of this kind of feature.

BTW, even this feature does not allow you to eliminate all checks on
nargout because it will fail (in Matlab) if you call fxn1 with no
output values to assign, so you still need to handle that case:

  function varargout = fxn1 (varargin)
    if (nargout > 0)
      varargout = cell (nargout, 1);
      [varargout{:}] = fxn2 (varargin{:});
    else
      fxn2 (varargin{:});
    endif
  endfunction

But this seems like a missing feature/bug in Matlab.  Why not simply
set nargout to 0 if varargout is empty in the expression
[varargout{:}]?  Am I missing something here?

jwe



-------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.

Octave's home on the web:  http://www.octave.org
How to fund new projects:  http://www.octave.org/funding.html
Subscription information:  http://www.octave.org/archive.html
-------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]