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 |
"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 |
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 |
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 |
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 |
In reply to this post by Jose
Right, so there we have "informally documented" undocumented Matlab behavior :-) Pic attached of what ML r2014a makes of it. Philip |
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 |
Free forum by Nabble | Edit this page |