Handling variable number of output arguments in multi-level function calls

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Handling variable number of output arguments in multi-level function calls

Jose
Dear community.

I often face the situation in which a function (say f1) calls another
function internally (say f2) whose number of outputs depends on the
number of outputs requested from the upper calling function f1.
Something like this
--->
function [o1,o2]=f1(varargin)
   ...
   if nargout==1
     [o1]=f2(varargin{:});
   elseif nargout==2
     [o1,o2]=f2(varargin{:});
   endif
   ...
endfunction
<---
This example shows how I am handling the problem of calling f2 with the
right number of output arguments. I suspect that this is something that
other users also face often, and I also suspect that there might be a
better way to handle this (one can imagine easily how the code gets
cluttered in case there are many output arguments).

Does somebody know a more elegant (and perhaps more efficient?) way to
handle this?

Thanks in advance and kind regards,
José

_______________________________________________
Help-octave mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-octave
Reply | Threaded
Open this post in threaded view
|

Re: Handling variable number of output arguments in multi-level function calls

Philip Nienhuis
Jose wrote
Dear community.

I often face the situation in which a function (say f1) calls another
function internally (say f2) whose number of outputs depends on the
number of outputs requested from the upper calling function f1.
Something like this
--->
function [o1,o2]=f1(varargin)
   ...
   if nargout==1
     [o1]=f2(varargin{:});
   elseif nargout==2
     [o1,o2]=f2(varargin{:});
   endif
   ...
endfunction
<---
This example shows how I am handling the problem of calling f2 with the
right number of output arguments. I suspect that this is something that
other users also face often, and I also suspect that there might be a
better way to handle this (one can imagine easily how the code gets
cluttered in case there are many output arguments).

Does somebody know a more elegant (and perhaps more efficient?) way to
handle this?
"code gets cluttered" - that depends on what one calls "cluttered". That's a question of coding discipline.
There are the standard ways to keep code readable and maintainable as much as possible:
- code layout
- subfunctions
- to-the-point comments
- plus more sophisticated stuff (doxygen, ...)

AFAIK nargout is the most suitable way to deal with output depending on the number of requested output args.

There are other ways, like
[~, ~, outarg3, ~, outarg5] = foobar (varargin)
that uses only output arguments #3 and#5 and skips the rest. But then the selection of which outargs to use is made by the caller, not the called function (foobar). Then foobar() will always compute all output args, whether requested or not , which depending on the case at hand may be a negligible or significant waste of CPU cycles.

Another way is to return outputs (don't forget to at least initialize all) depending on the number of input args to foobar().

I think that's about all the choice there is.

Philip
Reply | Threaded
Open this post in threaded view
|

Re: Handling variable number of output arguments in multi-level function calls

Juan Pablo Carbajal-2
On Fri, Dec 12, 2014 at 1:21 PM, Philip Nienhuis
<[hidden email]> wrote:

> Jose wrote
>> Dear community.
>>
>> I often face the situation in which a function (say f1) calls another
>> function internally (say f2) whose number of outputs depends on the
>> number of outputs requested from the upper calling function f1.
>> Something like this
>> --->
>> function [o1,o2]=f1(varargin)
>>    ...
>>    if nargout==1
>>      [o1]=f2(varargin{:});
>>    elseif nargout==2
>>      [o1,o2]=f2(varargin{:});
>>    endif
>>    ...
>> endfunction
>> <---
>> This example shows how I am handling the problem of calling f2 with the
>> right number of output arguments. I suspect that this is something that
>> other users also face often, and I also suspect that there might be a
>> better way to handle this (one can imagine easily how the code gets
>> cluttered in case there are many output arguments).
>>
>> Does somebody know a more elegant (and perhaps more efficient?) way to
>> handle this?
>
> "code gets cluttered" - that depends on what one calls "cluttered". That's a
> question of coding discipline.
> There are the standard ways to keep code readable and maintainable as much
> as possible:
> - code layout
> - subfunctions
> - to-the-point comments
> - plus more sophisticated stuff (doxygen, ...)
>
> AFAIK nargout is the most suitable way to deal with output depending on the
> number of requested output args.
>
> There are other ways, like
> [~, ~, outarg3, ~, outarg5] = foobar (varargin)
> that uses only output arguments #3 and#5 and skips the rest. But then the
> selection of which outargs to use is made by the caller, not the called
> function (foobar). Then foobar() will always compute all output args,
> whether requested or not , which depending on the case at hand may be a
> negligible or significant waste of CPU cycles.
>
> Another way is to return outputs (don't forget to at least initialize all)
> depending on the number of input args to foobar().
>
> I think that's about all the choice there is.
>
> Philip
>
>
>
> --
> View this message in context: http://octave.1599824.n4.nabble.com/Handling-variable-number-of-output-arguments-in-multi-level-function-calls-tp4667761p4667763.html
> Sent from the Octave - General mailing list archive at Nabble.com.
>
> _______________________________________________
> Help-octave mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/help-octave

If you use varargout in your f1 function, then you could do

OUT = nthargout (1:nargout, @f2, varargin{:});

and then distribute the cell OUT in the outputs of f1. I think you
will have to have a special check for the case nargout=1.

_______________________________________________
Help-octave mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-octave
Reply | Threaded
Open this post in threaded view
|

Re: Handling variable number of output arguments in multi-level function calls

Jose
In reply to this post by Philip Nienhuis
Hello Philip, thanks for the answer.

On 12/12/14 14:21, Philip Nienhuis wrote:
>
> AFAIK nargout is the most suitable way to deal with output depending on the
> number of requested output args.

Yes, that seems to be the case. I have just found
http://stackoverflow.com/questions/4895556/how-to-wrap-a-function-using-varargin-and-varargout
with an example of how to do it.

As a side-note, I think there is a small Matlab/Octave compatibility
issue here. Following the solution provided by SCFrench (who works for
The MathWorks) I do the following test in Octave:
--->
octave:75> function varargout = wrapper( varargin )
 > [varargout{1:nargout}] = sin( varargin{:} );
 > endfunction
octave:76> wrapper(0)
octave:77> a=wrapper(0)
a = 0
octave:78> sin(0)
ans = 0
<---
So I guess this solution does not work in Octave as in Matlab when the
outer-most function is called with no output arguments. I cannot
double-check in Matlab, as I do not have it. Can somebody please
confirm? If so I can then file a report.

Regards,
José.

_______________________________________________
Help-octave mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-octave
Reply | Threaded
Open this post in threaded view
|

Re: Handling variable number of output arguments in multi-level function calls

Jose
In reply to this post by Juan Pablo Carbajal-2
On 12/12/14 14:41, Juan Pablo Carbajal wrote:
> If you use varargout in your f1 function, then you could do
>
> OUT = nthargout (1:nargout, @f2, varargin{:});
>
> and then distribute the cell OUT in the outputs of f1. I think you
> will have to have a special check for the case nargout=1.

That is a possibility as well, thanks. For completeness:
--->
function [o1,o2]=f1(varargin)
   o1=1;
   o2=2;
endfunction

function varargout=f2(varargin)
   if nargout==0, varargout{1}=f1(varargin{:}); return; endif
   OUT=nthargout (1:nargout, @f1, varargin{:});
   if nargout==1,
     varargout{1}=OUT;
   else
     varargout= OUT;
   endif
endfunction
<---
Using this we have
--->
octave:3> f2
ans =  1
octave:4> a=f2
a =  1
octave:5> [a,b]=f2
a =  1
b =  2
<---


J.


>
> _______________________________________________
> Help-octave mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/help-octave
>


_______________________________________________
Help-octave mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-octave
Reply | Threaded
Open this post in threaded view
|

Re: Handling variable number of output arguments in multi-level function calls

Philip Nienhuis
In reply to this post by Jose
Jose wrote
Hello Philip, thanks for the answer.

On 12/12/14 14:21, Philip Nienhuis wrote:
>
> AFAIK nargout is the most suitable way to deal with output depending on the
> number of requested output args.

Yes, that seems to be the case. I have just found
http://stackoverflow.com/questions/4895556/how-to-wrap-a-function-using-varargin-and-varargout
with an example of how to do it.

As a side-note, I think there is a small Matlab/Octave compatibility
issue here. Following the solution provided by SCFrench (who works for
Right, so there we have "informally documented" undocumented Matlab behavior :-)

The MathWorks) I do the following test in Octave:
--->
octave:75> function varargout = wrapper( varargin )
 > [varargout{1:nargout}] = sin( varargin{:} );
 > endfunction
octave:76> wrapper(0)
octave:77> a=wrapper(0)
a = 0
octave:78> sin(0)
ans = 0
<---
So I guess this solution does not work in Octave as in Matlab when the
outer-most function is called with no output arguments. I cannot
double-check in Matlab, as I do not have it. Can somebody please
confirm? If so I can then file a report.
Pic attached of what ML r2014a makes of it.

Philip
Reply | Threaded
Open this post in threaded view
|

Re: Handling variable number of output arguments in multi-level function calls

Jose
On 13/12/14 00:13, Philip Nienhuis wrote:
>> As a side-note, I think there is a small Matlab/Octave compatibility
>> issue here. Following the solution provided by SCFrench (who works for
>
> Right, so there we have "informally documented" undocumented Matlab behavior
> :-)

Yes, that is the case :).

Thanks for the confirmation. Bug #43813 reported.

Regards,
J.


_______________________________________________
Help-octave mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/help-octave