Forcing Variable Outputs

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Forcing Variable Outputs

Bill Denney
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?

Bill

--
From Dumblaws.com:  In China, to go to college you must be intelligent.



-------------------------------------------------------------
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 | Threaded
Open this post in threaded view
|

Re: Forcing Variable Outputs

Geordie McBain
Does this do what you want?

  function varargout = fxn1 (varargin)
    varargout = fxn2 (varargin{:});
  endfunction

  function varargout = fxn2 (varargin)
    varargout = {varargin};
  endfunction

I see:

octave2.9:1> a = fxn1 (1)
a = 1
octave2.9:2> [a, b] = fxn1 (1, 2)
a = 1
b = 2


On Tue, 2006-03-28 at 20:53 -0500, 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?
>
> Bill
>



-------------------------------------------------------------
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 | Threaded
Open this post in threaded view
|

Re: Forcing Variable Outputs

Bill Denney
Not exactly.  As I tried that, it just gave the output as the same as the
input.  The problem is that I want this to work correctly (without having
to do a lot of if blocks).

function [varargout] = fxn1(varargin)

   nargin
   nargout

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

endfunction

function [varargout] = fxn2(varargin)

   nargin
   nargout

   varargout = {varargin};

endfunction

As it is, if I call

[a b c] = fxn1(1, 2, 3)

I get that nargin for fxn1 is 3, and nargin for fxn2 is 3, but nargout for
fxn1 is 3 and nargout for fxn2 is 1.

Bill

On Wed, 29 Mar 2006, Geordie McBain wrote:

> Does this do what you want?
>
>  function varargout = fxn1 (varargin)
>    varargout = fxn2 (varargin{:});
>  endfunction
>
>  function varargout = fxn2 (varargin)
>    varargout = {varargin};
>  endfunction
>
> I see:
>
> octave2.9:1> a = fxn1 (1)
> a = 1
> octave2.9:2> [a, b] = fxn1 (1, 2)
> a = 1
> b = 2
>
>
> On Tue, 2006-03-28 at 20:53 -0500, 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?
>>
>> Bill
>>
>

--
"I love America more than any other country in this world, and, exactly
for this reason, I insist on the right to criticize her perpetually."
   -- James Baldwin



-------------------------------------------------------------
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 | Threaded
Open this post in threaded view
|

Forcing Variable Outputs

John W. Eaton-6
In reply to this post by Bill Denney
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 | Threaded
Open this post in threaded view
|

Re: Forcing Variable Outputs

Bill Denney
On Wed, 29 Mar 2006, John W. Eaton wrote:

> 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.

That's exactly what I'm wanting (I didn't realize that it was a matlab
feature).

> 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.

I realize that this is a complex case, and I would think it would be
feasible to require the LHS to be an expanded cell of some type for it to
be evaluated.

> 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.

I think that I would be very helpful to hit the 90% of cases.  I
acknowledge that this is probably a relatively rare request of the
interpreter.  The reason that I was wanting it is I was trying to write an
ndgrid function that is the same as meshgrid, but with the first two input
and output arguements swapped.  Meshgrid takes an arbitrary list of
arguements and an equal number of output arguements.  I could fudge it by
just making nargout=nargin, but I was wanting to do it right.

> 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?

That makes complete sense to me.

Bill

--
"Be who you are and say what you feel, because those who mind don't
matter and those who matter don't mind."
   -- Dr. Suess



-------------------------------------------------------------
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
-------------------------------------------------------------