Mercurial > hg > octave-nkf
changeset 6510:cbae86745c5b
[project @ 2007-04-09 23:15:47 by jwe]
author | jwe |
---|---|
date | Mon, 09 Apr 2007 23:15:47 +0000 |
parents | 84f2d0253aea |
children | 73ce4e14d35d |
files | doc/ChangeLog doc/interpreter/func.txi scripts/ChangeLog scripts/plot/__go_draw_axes__.m |
diffstat | 4 files changed, 213 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2007-04-09 Søren Hauberg <hauberg@gmail.com> + + * interpreter/func.txi: Document varargin, varargout, and default + argument values. + 2007-04-03 Rafael Laboissiere <rafael@debian.org> * interpreter/basics.txi: Clarified some limitations of the #!
--- a/doc/interpreter/func.txi +++ b/doc/interpreter/func.txi @@ -20,6 +20,7 @@ * Variable-length Argument Lists:: * Variable-length Return Lists:: * Returning From a Function:: +* Default Arguments:: * Function Files:: * Script Files:: * Dynamically Linked Functions:: @@ -88,7 +89,7 @@ be empty, in which case this form is equivalent to the one shown above. To print a message along with ringing the bell, you might modify the -@code{beep} to look like this: +@code{wakeup} to look like this: @example @group @@ -321,11 +322,114 @@ @section Variable-length Argument Lists @cindex variable-length argument lists @cindex @code{...} +Sometimes the number of input arguments is not known when the function +is defined. As an example think of a function that returns the smallest +of all its input arguments. For example, + +@example +a = smallest (1, 2, 3); +b = smallest (1, 2, 3, 4); +@end example + +@noindent +In this example both @code{a} and @code{b} would be 1. One way to write +the @code{smallest} function is + +@example +function val = smallest (arg1, arg2, arg3, arg4, arg5) + @var{body} +endfunction +@end example + +@noindent +and then use the value of @code{nargin} to determine which of the input +arguments should be considered. The problem with this approach is +that it can only handle a limited number of input arguments. + +Octave supports the @code{varargin} keyword for handling a variable +number of input arguments. Using @code{varargin} the function +looks like this + +@example +function val = smallest (varargin) + @var{body} +endfunction +@end example + +@noindent +In the function body the input arguments can be accessed through the +variable @code{varargin}. This variable is a cell array containing +all the input arguments. @xref{Cell Arrays}, for details on working +with cell arrays. The @code{smallest} function can now be defined +like this + +@example +function val = smallest (varargin) + val = min ([varargin@{:@}]); +endfunction +@end example + +@noindent +This implementation handles any number of input arguments, but it's also +a very simple solution to the problem. + +A slightly more complex example of @code{varargin} is a function +@code{print_arguments} that prints all input arguments. Such a function +can be defined like this + +@example +function print_arguments (varargin) + for i = 1:length (varargin) + printf ("Input argument %d: ", i); + disp (varargin@{i@}); + endfor +endfunction +@end example + +@noindent +This function produces output like this + +@example +@group +print_arguments (1, "two", 3); + @print{} Input argument 1: 1 + @print{} Input argument 2: two + @print{} Input argument 3: 3 +@end group +@end example @node Variable-length Return Lists @section Variable-length Return Lists @cindex variable-length return lists -@cindex @code{...} +It is possible to return a variable number of output arguments from a +function using a syntax that's similar to the one used with the +@code{varargin} keyword. To let a function return a variable number of +output arguments the @code{varargout} keyword is used. As with +@code{varargin} @code{varargout} is a cell array that will contain the +requested output arguments. + +As an example the following function sets the first output argument to +1, the second to 2, and so on. + +@example +function varargout = one_to_n () + for i = 1:nargout + varargout@{i@} = i; + endfor +endfunction +@end example + +@noindent +When called this function returns values like this + +@example +@group +[a, b, c] = one_to_n () + @result{} a = 1 + @result{} b = 2 + @result{} c = 3 +@end group +@end example @node Returning From a Function @section Returning From a Function @@ -377,6 +481,61 @@ @DOCSTRING(return_last_computed_value) +@node Default Arguments +@section Default Arguments +@cindex default arguments + +Since Octave supports variable number of input arguments, it is very useful +to assign default values to some input arguments. When an input argument +is declared in the argument list it is possible to assign a default +value to the argument like this + +@example +function @var{name} (@var{arg1} = @var{val1}, @dots{}) + @var{body} +endfunction +@end example + +@noindent +If no value is assigned to @var{arg1} by the user, it will have the +value @var{val1}. + +As an example, the following function implements a variant of the classic +``Hello, World'' program. +@example +function hello (who = "World") + printf ("Hello, %s!\n", who); +endfunction +@end example + +@noindent +When called without an input argument the function prints the following +@example +@group +hello (); + @print{} Hello, World! +@end group +@end example + +@noindent +and when it's called with an input argument it prints the following +@example +@group +hello ("Beautiful World of Free Software"); + @print{} Hello, Beautiful World of Free Software! +@end group +@end example + +Sometimes it is useful to explicitly tell Octave to use the default value +of an input argument. This can be done writing a @samp{:} as the value +of the input argument when calling the function. +@example +@group +hello (:); + @print{} Hello, World! +@end group +@end example + @node Function Files @section Function Files @cindex function file @@ -581,8 +740,6 @@ Here is the complete text of @file{oregonator.cc}: -just - @example @group #include <octave/oct.h>
--- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,8 @@ +2007-04-09 John W. Eaton <jwe@octave.org> + + * plot/__go_draw_axes__.m (__gnuplot_write_data__): New function. + (__go_draw_axes__): Use it to write data to plot stream. + 2007-04-09 Daniel J Sebald <daniel.sebald@ieee.org> * plot/stem.m: Fix typos in doc string. Fix typo in call to
--- a/scripts/plot/__go_draw_axes__.m +++ b/scripts/plot/__go_draw_axes__.m @@ -663,23 +663,7 @@ if (is_image_data(i)) fwrite (plot_stream, data{i}, "float32"); else - if (nd == 2) - fprintf (plot_stream, - strcat (repmat ("%g ", 1, rows (data{i})), "\n"), - data{i}); - else - if (parametric(i)) - fprintf (plot_stream, "%g %g %g\n", data{i}); - else - tmp = data{i}; - nc = columns (tmp); - for j = 1:3:nc - fprintf (plot_stream, "%g %g %g\n", tmp(:,j:j+2)'); - fputs (plot_stream, "\n"); - endfor - endif - endif - fputs (plot_stream, "e\n"); + __gnuplot_write_data__ (plot_stream, data{i}, nd, parametric(i)); endif endfor else @@ -896,3 +880,44 @@ fputs (plot_stream, ";\n"); endfunction + +function __gnuplot_write_data__ (plot_stream, data, nd, parametric) + + ## DATA is already transposed. + + ## FIXME -- this may need to be converted to C++ for speed. + + if (nd == 2) + nan_elts = find (sum (isnan (data))); + fmt = strcat (repmat ("%g ", 1, rows (data)), "\n"); + if (isempty (nan_elts)) + fprintf (plot_stream, fmt, data); + else + n = columns (data); + have_nans = true; + num_nan_elts = numel (nan_elts); + k = 1; + for i = 1:n + if (have_nans && i == nan_elts(k)) + fputs (plot_stream, "\n"); + have_nans = ++k <= num_nan_elts; + else + fprintf (plot_stream, fmt, data(:,i)); + endif + endfor + endif + else + ## FIXME -- handle NaNs here too? + if (parametric) + fprintf (plot_stream, "%g %g %g\n", data); + else + nc = columns (data); + for j = 1:3:nc + fprintf (plot_stream, "%g %g %g\n", data(:,j:j+2)'); + fputs (plot_stream, "\n"); + endfor + endif + endif + fputs (plot_stream, "e\n"); + +endfunction