Mercurial > octave-nkf
diff doc/interpreter/func.txi @ 3294:bfe1573bd2ae
[project @ 1999-10-19 10:06:07 by jwe]
author | jwe |
---|---|
date | Tue, 19 Oct 1999 10:08:42 +0000 |
parents | |
children | 86873384cd10 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/interpreter/func.txi Tue Oct 19 10:08:42 1999 +0000 @@ -0,0 +1,1081 @@ +@c Copyright (C) 1996, 1997 John W. Eaton +@c This is part of the Octave manual. +@c For copying conditions, see the file gpl.texi. + +@node Functions and Scripts, Error Handling, Statements, Top +@chapter Functions and Script Files +@cindex defining functions +@cindex user-defined functions +@cindex functions, user-defined +@cindex script files + +Complicated Octave programs can often be simplified by defining +functions. Functions can be defined directly on the command line during +interactive Octave sessions, or in external files, and can be called just +like built-in functions. + +@menu +* Defining Functions:: +* Multiple Return Values:: +* Variable-length Argument Lists:: +* Variable-length Return Lists:: +* Returning From a Function:: +* Function Files:: +* Script Files:: +* Dynamically Linked Functions:: +* Organization of Functions:: +@end menu + +@node Defining Functions, Multiple Return Values, Functions and Scripts, Functions and Scripts +@section Defining Functions +@cindex @code{function} statement +@cindex @code{endfunction} statement + +In its simplest form, the definition of a function named @var{name} +looks like this: + +@example +@group +function @var{name} + @var{body} +endfunction +@end group +@end example + +@noindent +A valid function name is like a valid variable name: a sequence of +letters, digits and underscores, not starting with a digit. Functions +share the same pool of names as variables. + +The function @var{body} consists of Octave statements. It is the +most important part of the definition, because it says what the function +should actually @emph{do}. + +For example, here is a function that, when executed, will ring the bell +on your terminal (assuming that it is possible to do so): + +@example +@group +function wakeup + printf ("\a"); +endfunction +@end group +@end example + +The @code{printf} statement (@pxref{Input and Output}) simply tells +Octave to print the string @code{"\a"}. The special character @samp{\a} +stands for the alert character (ASCII 7). @xref{Strings}. + +Once this function is defined, you can ask Octave to evaluate it by +typing the name of the function. + +Normally, you will want to pass some information to the functions you +define. The syntax for passing parameters to a function in Octave is + +@example +@group +function @var{name} (@var{arg-list}) + @var{body} +endfunction +@end group +@end example + +@noindent +where @var{arg-list} is a comma-separated list of the function's +arguments. When the function is called, the argument names are used to +hold the argument values given in the call. The list of arguments may +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: + +@example +@group +function wakeup (message) + printf ("\a%s\n", message); +endfunction +@end group +@end example + +Calling this function using a statement like this + +@example +wakeup ("Rise and shine!"); +@end example + +@noindent +will cause Octave to ring your terminal's bell and print the message +@samp{Rise and shine!}, followed by a newline character (the @samp{\n} +in the first argument to the @code{printf} statement). + +In most cases, you will also want to get some information back from the +functions you define. Here is the syntax for writing a function that +returns a single value: + +@example +@group +function @var{ret-var} = @var{name} (@var{arg-list}) + @var{body} +endfunction +@end group +@end example + +@noindent +The symbol @var{ret-var} is the name of the variable that will hold the +value to be returned by the function. This variable must be defined +before the end of the function body in order for the function to return +a value. + +Variables used in the body of a function are local to the +function. Variables named in @var{arg-list} and @var{ret-var} are also +local to the function. @xref{Global Variables}, for information about +how to access global variables inside a function. + +For example, here is a function that computes the average of the +elements of a vector: + +@example +@group +function retval = avg (v) + retval = sum (v) / length (v); +endfunction +@end group +@end example + +If we had written @code{avg} like this instead, + +@example +@group +function retval = avg (v) + if (is_vector (v)) + retval = sum (v) / length (v); + endif +endfunction +@end group +@end example + +@noindent +and then called the function with a matrix instead of a vector as the +argument, Octave would have printed an error message like this: + +@example +@group +error: `retval' undefined near line 1 column 10 +error: evaluating index expression near line 7, column 1 +@end group +@end example + +@noindent +because the body of the @code{if} statement was never executed, and +@code{retval} was never defined. To prevent obscure errors like this, +it is a good idea to always make sure that the return variables will +always have values, and to produce meaningful error messages when +problems are encountered. For example, @code{avg} could have been +written like this: + +@example +@group +function retval = avg (v) + retval = 0; + if (is_vector (v)) + retval = sum (v) / length (v); + else + error ("avg: expecting vector argument"); + endif +endfunction +@end group +@end example + +There is still one additional problem with this function. What if it is +called without an argument? Without additional error checking, Octave +will probably print an error message that won't really help you track +down the source of the error. To allow you to catch errors like this, +Octave provides each function with an automatic variable called +@code{nargin}. Each time a function is called, @code{nargin} is +automatically initialized to the number of arguments that have actually +been passed to the function. For example, we might rewrite the +@code{avg} function like this: + +@example +@group +function retval = avg (v) + retval = 0; + if (nargin != 1) + usage ("avg (vector)"); + endif + if (is_vector (v)) + retval = sum (v) / length (v); + else + error ("avg: expecting vector argument"); + endif +endfunction +@end group +@end example + +Although Octave does not automatically report an error if you call a +function with more arguments than expected, doing so probably indicates +that something is wrong. Octave also does not automatically report an +error if a function is called with too few arguments, but any attempt to +use a variable that has not been given a value will result in an error. +To avoid such problems and to provide useful messages, we check for both +possibilities and issue our own error message. + +@defvr {Automatic Variable} nargin +When a function is called, this local variable is automatically +initialized to the number of arguments passed to the function. At the +top level, @code{nargin} holds the number of command line arguments that +were passed to Octave. +@end defvr + +@defvr {Built-in Variable} silent_functions +If the value of @code{silent_functions} is nonzero, internal output +from a function is suppressed. Otherwise, the results of expressions +within a function body that are not terminated with a semicolon will +have their values printed. The default value is 0. + +For example, if the function + +@example +function f () + 2 + 2 +endfunction +@end example + +@noindent +is executed, Octave will either print @samp{ans = 4} or nothing +depending on the value of @code{silent_functions}. +@end defvr + +@defvr {Built-in Variable} warn_missing_semicolon +If the value of this variable is nonzero, Octave will warn when +statements in function definitions don't end in semicolons. The default +value is 0. +@end defvr + +@node Multiple Return Values, Variable-length Argument Lists, Defining Functions, Functions and Scripts +@section Multiple Return Values + +Unlike many other computer languages, Octave allows you to define +functions that return more than one value. The syntax for defining +functions that return multiple values is + +@example +function [@var{ret-list}] = @var{name} (@var{arg-list}) + @var{body} +endfunction +@end example + +@noindent +where @var{name}, @var{arg-list}, and @var{body} have the same meaning +as before, and @var{ret-list} is a comma-separated list of variable +names that will hold the values returned from the function. The list of +return values must have at least one element. If @var{ret-list} has +only one element, this form of the @code{function} statement is +equivalent to the form described in the previous section. + +Here is an example of a function that returns two values, the maximum +element of a vector and the index of its first occurrence in the vector. + +@example +@group +function [max, idx] = vmax (v) + idx = 1; + max = v (idx); + for i = 2:length (v) + if (v (i) > max) + max = v (i); + idx = i; + endif + endfor +endfunction +@end group +@end example + +In this particular case, the two values could have been returned as +elements of a single array, but that is not always possible or +convenient. The values to be returned may not have compatible +dimensions, and it is often desirable to give the individual return +values distinct names. + +In addition to setting @code{nargin} each time a function is called, +Octave also automatically initializes @code{nargout} to the number of +values that are expected to be returned. This allows you to write +functions that behave differently depending on the number of values that +the user of the function has requested. The implicit assignment to the +built-in variable @code{ans} does not figure in the count of output +arguments, so the value of @code{nargout} may be zero. + +The @code{svd} and @code{lu} functions are examples of built-in +functions that behave differently depending on the value of +@code{nargout}. + +It is possible to write functions that only set some return values. For +example, calling the function + +@example +function [x, y, z] = f () + x = 1; + z = 2; +endfunction +@end example + +@noindent +as + +@example +[a, b, c] = f () +@end example + +@noindent +produces: + +@example +a = 1 + +b = [](0x0) + +c = 2 +@end example + +@noindent +provided that the built-in variable @code{define_all_return_values} is +nonzero and the value of @code{default_return_value} is @samp{[]}. +@xref{Summary of Built-in Variables}. + +@defvr {Automatic Variable} nargout +When a function is called, this local variable is automatically +initialized to the number of arguments expected to be returned. For +example, + +@example +f () +@end example + +@noindent +will result in @code{nargout} being set to 0 inside the function +@code{f} and + +@example +[s, t] = f () +@end example + +@noindent +will result in @code{nargout} being set to 2 inside the function +@code{f}. + +At the top level, @code{nargout} is undefined. +@end defvr + +@defvr {Built-in Variable} default_return_value +The value given to otherwise uninitialized return values if +@code{define_all_return_values} is nonzero. The default value is +@code{[]}. +@end defvr + +@defvr {Built-in Variable} define_all_return_values +If the value of @code{define_all_return_values} is nonzero, Octave +will substitute the value specified by @code{default_return_value} for +any return values that remain undefined when a function returns. The +default value is 0. +@end defvr + +@deftypefn {Function File} {} nargchk (@var{nargin_min}, @var{nargin_max}, @var{n}) +If @var{n} is in the range @var{nargin_min} through @var{nargin_max} +inclusive, return the empty matrix. Otherwise, return a message +indicating whether @var{n} is too large or too small. + +This is useful for checking to see that the number of arguments supplied +to a function is within an acceptable range. +@end deftypefn + +@node Variable-length Argument Lists, Variable-length Return Lists, Multiple Return Values, Functions and Scripts +@section Variable-length Argument Lists +@cindex Variable-length argument lists +@cindex @code{...} + +Octave has a real mechanism for handling functions that take an +unspecified number of arguments, so it is not necessary to place an +upper bound on the number of optional arguments that a function can +accept. + +@c XXX FIXME XXX -- should we add a note about why this feature is not +@c compatible with Matlab 5? + +Here is an example of a function that uses the new syntax to print a +header followed by an unspecified number of values: + +@example +function foo (heading, ...) + disp (heading); + va_start (); + ## Pre-decrement to skip `heading' arg. + while (--nargin) + disp (va_arg ()); + endwhile +endfunction +@end example + +The ellipsis that marks the variable argument list may only appear once +and must be the last element in the list of arguments. + +@deftypefn {Built-in Function} {} va_start () +Position an internal pointer to the first unnamed argument and allows +you to cycle through the arguments more than once. It is not necessary +to call @code{va_start} if you do not plan to cycle through the +arguments more than once. This function may only be called inside +functions that have been declared to accept a variable number of input +arguments. +@end deftypefn + +@deftypefn {Built-in Function} {} va_arg () +Return the value of the next available argument and move the internal +pointer to the next argument. It is an error to call @code{va_arg()} +when there are no more arguments available. +@end deftypefn + +Sometimes it is useful to be able to pass all unnamed arguments to +another function. The keyword @var{all_va_args} makes this very easy to +do. For example, + +@example +@group +function f (...) + while (nargin--) + disp (va_arg ()) + endwhile +endfunction + +function g (...) + f ("begin", all_va_args, "end") +endfunction + +g (1, 2, 3) + + @print{} begin + @print{} 1 + @print{} 2 + @print{} 3 + @print{} end +@end group +@end example + +@defvr {Keyword} all_va_args +This keyword stands for the entire list of optional argument, so it is +possible to use it more than once within the same function without +having to call @code{va_start}. It can only be used within functions +that take a variable number of arguments. It is an error to use it in +other contexts. +@end defvr + +@node Variable-length Return Lists, Returning From a Function, Variable-length Argument Lists, Functions and Scripts +@section Variable-length Return Lists +@cindex Variable-length return lists +@cindex @code{...} + +Octave also has a real mechanism for handling functions that return an +unspecified number of values, so it is no longer necessary to place an +upper bound on the number of outputs that a function can produce. + +Here is an example of a function that uses a variable-length return list +to produce @var{n} values: + +@example +@group +function [...] = f (n, x) + for i = 1:n + vr_val (i * x); + endfor +endfunction + +[dos, quatro] = f (2, 2) + @result{} dos = 2 + @result{} quatro = 4 +@end group +@end example + +As with variable argument lists, the ellipsis that marks the variable +return list may only appear once and must be the last element in the +list of returned values. + +@deftypefn {Built-in Function} {} vr_val (@var{val}) +Each time this function is called, it places the value of its argument +at the end of the list of values to return from the current function. +Once @code{vr_val} has been called, there is no way to go back to the +beginning of the list and rewrite any of the return values. This +function may only be called within functions that have been declared to +return an unspecified number of output arguments (by using the special +ellipsis notation described above). +@end deftypefn + +@node Returning From a Function, Function Files, Variable-length Return Lists, Functions and Scripts +@section Returning From a Function + +The body of a user-defined function can contain a @code{return} statement. +This statement returns control to the rest of the Octave program. It +looks like this: + +@example +return +@end example + +Unlike the @code{return} statement in C, Octave's @code{return} +statement cannot be used to return a value from a function. Instead, +you must assign values to the list of return variables that are part of +the @code{function} statement. The @code{return} statement simply makes +it easier to exit a function from a deeply nested loop or conditional +statement. + +Here is an example of a function that checks to see if any elements of a +vector are nonzero. + +@example +@group +function retval = any_nonzero (v) + retval = 0; + for i = 1:length (v) + if (v (i) != 0) + retval = 1; + return; + endif + endfor + printf ("no nonzero elements found\n"); +endfunction +@end group +@end example + +Note that this function could not have been written using the +@code{break} statement to exit the loop once a nonzero value is found +without adding extra logic to avoid printing the message if the vector +does contain a nonzero element. + +@defvr {Keyword} return +When Octave encounters the keyword @code{return} inside a function or +script, it returns control to be caller immediately. At the top level, +the return statement is ignored. A @code{return} statement is assumed +at the end of every function definition. +@end defvr + +@defvr {Built-in Variable} return_last_computed_value +If the value of @code{return_last_computed_value} is true, and a +function is defined without explicitly specifying a return value, the +function will return the value of the last expression. Otherwise, no +value will be returned. The default value is 0. + +For example, the function + +@example +function f () + 2 + 2; +endfunction +@end example + +@noindent +will either return nothing, if the value of +@code{return_last_computed_value} is 0, or 4, if the value of +@code{return_last_computed_value} is nonzero. +@end defvr + +@node Function Files, Script Files, Returning From a Function, Functions and Scripts +@section Function Files +@cindex function file + +Except for simple one-shot programs, it is not practical to have to +define all the functions you need each time you need them. Instead, you +will normally want to save them in a file so that you can easily edit +them, and save them for use at a later time. + +Octave does not require you to load function definitions from files +before using them. You simply need to put the function definitions in a +place where Octave can find them. + +When Octave encounters an identifier that is undefined, it first looks +for variables or functions that are already compiled and currently +listed in its symbol table. If it fails to find a definition there, it +searches the list of directories specified by the built-in variable +@code{LOADPATH} for files ending in @file{.m} that have the same base +name as the undefined identifier.@footnote{The @samp{.m} suffix was +chosen for compatibility with @sc{Matlab}.} Once Octave finds a file +with a name that matches, the contents of the file are read. If it +defines a @emph{single} function, it is compiled and executed. +@xref{Script Files}, for more information about how you can define more +than one function in a single file. + +When Octave defines a function from a function file, it saves the full +name of the file it read and the time stamp on the file. After +that, it checks the time stamp on the file every time it needs the +function. If the time stamp indicates that the file has changed since +the last time it was read, Octave reads it again. + +Checking the time stamp allows you to edit the definition of a function +while Octave is running, and automatically use the new function +definition without having to restart your Octave session. Checking the +time stamp every time a function is used is rather inefficient, but it +has to be done to ensure that the correct function definition is used. + +To avoid degrading performance unnecessarily by checking the time stamps +on functions that are not likely to change, Octave assumes that function +files in the directory tree +@file{@var{octave-home}/share/octave/@var{version}/m} +will not change, so it doesn't have to check their time stamps every time the +functions defined in those files are used. This is normally a very good +assumption and provides a significant improvement in performance for the +function files that are distributed with Octave. + +If you know that your own function files will not change while you are +running Octave, you can improve performance by setting the variable +@code{ignore_function_time_stamp} to @code{"all"}, so that Octave will +ignore the time stamps for all function files. Setting it to +@code{"system"} gives the default behavior. If you set it to anything +else, Octave will check the time stamps on all function files. + +@c XXX FIXME XXX -- note about time stamps on files in NFS environments? + +@defvr {Built-in Variable} DEFAULT_LOADPATH +A colon separated list of directories in which to search for function +files by default. The value of this variable is also automatically +substituted for leading, trailing, or doubled colons that appear in the +built-in variable @code{LOADPATH}. +@end defvr + +@defvr {Built-in Variable} LOADPATH +A colon separated list of directories in which to search for function +files. @xref{Functions and Scripts}. The value of @code{LOADPATH} +overrides the environment variable @code{OCTAVE_PATH}. @xref{Installation}. + +@code{LOADPATH} is now handled in the same way as @TeX{} handles +@code{TEXINPUTS}. Leading, trailing, or doubled colons that appear in +@code{LOADPATH} are replaced by the value of @code{DEFAULT_LOADPATH}. +The default value of @code{LOADPATH} is @code{":"}, which tells Octave +to search in the directories specified by @code{DEFAULT_LOADPATH}. + +In addition, if any path element ends in @samp{//}, that directory and +all subdirectories it contains are searched recursively for function +files. This can result in a slight delay as Octave caches the lists of +files found in the @code{LOADPATH} the first time Octave searches for a +function. After that, searching is usually much faster because Octave +normally only needs to search its internal cache for files. + +To improve performance of recursive directory searching, it is best for +each directory that is to be searched recursively to contain +@emph{either} additional subdirectories @emph{or} function files, but +not a mixture of both. + +@xref{Organization of Functions} for a description of the function file +directories that are distributed with Octave. +@end defvr + +@defvr {Built-in Variable} ignore_function_time_stamp +This variable can be used to prevent Octave from making the system call +@code{stat} each time it looks up functions defined in function files. +If @code{ignore_function_time_stamp} to @code{"system"}, Octave will not +automatically recompile function files in subdirectories of +@file{@var{octave-home}/lib/@var{version}} if they have changed since +they were last compiled, but will recompile other function files in the +@code{LOADPATH} if they change. If set to @code{"all"}, Octave will not +recompile any function files unless their definitions are removed with +@code{clear}. For any other value of @code{ignore_function_time_stamp}, +Octave will always check to see if functions defined in function files +need to recompiled. The default value of @code{ignore_function_time_stamp} is +@code{"system"}. +@end defvr + +@defvr {Built-in Variable} warn_function_name_clash +If the value of @code{warn_function_name_clash} is nonzero, a warning is +issued when Octave finds that the name of a function defined in a +function file differs from the name of the file. (If the names +disagree, the name declared inside the file is ignored.) If the value +is 0, the warning is omitted. The default value is 1. +@end defvr + +@node Script Files, Dynamically Linked Functions, Function Files, Functions and Scripts +@section Script Files + +A script file is a file containing (almost) any sequence of Octave +commands. It is read and evaluated just as if you had typed each +command at the Octave prompt, and provides a convenient way to perform a +sequence of commands that do not logically belong inside a function. + +Unlike a function file, a script file must @emph{not} begin with the +keyword @code{function}. If it does, Octave will assume that it is a +function file, and that it defines a single function that should be +evaluated as soon as it is defined. + +A script file also differs from a function file in that the variables +named in a script file are not local variables, but are in the same +scope as the other variables that are visible on the command line. + +Even though a script file may not begin with the @code{function} +keyword, it is possible to define more than one function in a single +script file and load (but not execute) all of them at once. To do +this, the first token in the file (ignoring comments and other white +space) must be something other than @code{function}. If you have no +other statements to evaluate, you can use a statement that has no +effect, like this: + +@example +@group +# Prevent Octave from thinking that this +# is a function file: + +1; + +# Define function one: + +function one () + ... +@end group +@end example + +To have Octave read and compile these functions into an internal form, +you need to make sure that the file is in Octave's @code{LOADPATH}, then +simply type the base name of the file that contains the commands. +(Octave uses the same rules to search for script files as it does to +search for function files.) + +If the first token in a file (ignoring comments) is @code{function}, +Octave will compile the function and try to execute it, printing a +message warning about any non-whitespace characters that appear after +the function definition. + +Note that Octave does not try to look up the definition of any identifier +until it needs to evaluate it. This means that Octave will compile the +following statements if they appear in a script file, or are typed at +the command line, + +@example +@group +# not a function file: +1; +function foo () + do_something (); +endfunction +function do_something () + do_something_else (); +endfunction +@end group +@end example + +@noindent +even though the function @code{do_something} is not defined before it is +referenced in the function @code{foo}. This is not an error because +Octave does not need to resolve all symbols that are referenced by a +function until the function is actually evaluated. + +Since Octave doesn't look for definitions until they are needed, the +following code will always print @samp{bar = 3} whether it is typed +directly on the command line, read from a script file, or is part of a +function body, even if there is a function or script file called +@file{bar.m} in Octave's @code{LOADPATH}. + +@example +@group +eval ("bar = 3"); +bar +@end group +@end example + +Code like this appearing within a function body could fool Octave if +definitions were resolved as the function was being compiled. It would +be virtually impossible to make Octave clever enough to evaluate this +code in a consistent fashion. The parser would have to be able to +perform the call to @code{eval} at compile time, and that would be +impossible unless all the references in the string to be evaluated could +also be resolved, and requiring that would be too restrictive (the +string might come from user input, or depend on things that are not +known until the function is evaluated). + +Although Octave normally executes commands from script files that have +the name @file{@var{file}.m}, you can use the function @code{source} to +execute commands from any file. + +@deftypefn {Built-in Function} {} source (@var{file}) +Parse and execute the contents of @var{file}. This is equivalent to +executing commands from a script file, but without requiring the file to +be named @file{@var{file}.m}. +@end deftypefn + +@node Dynamically Linked Functions, Organization of Functions, Script Files, Functions and Scripts +@section Dynamically Linked Functions +@cindex dynamic linking + +On some systems, Octave can dynamically load and execute functions +written in C++. Octave can only directly call functions written in C++, +but you can also load functions written in other languages +by calling them from a simple wrapper function written in C++. + +Here is an example of how to write a C++ function that Octave can load, +with commentary. The source for this function is included in the source +distributions of Octave, in the file @file{examples/oregonator.cc}. It +defines the same set of differential equations that are used in the +example problem of @ref{Ordinary Differential Equations}. By running +that example and this one, we can compare the execution times to see +what sort of increase in speed you can expect by using dynamically +linked functions. + +The function defined in @file{oregonator.cc} contains just 8 statements, +and is not much different than the code defined in the corresponding +M-file (also distributed with Octave in the file +@file{examples/oregonator.m}). + +Here is the complete text of @file{oregonator.cc}: + +just + +@example +@group +#include <octave/oct.h> + +DEFUN_DLD (oregonator, args, , + "The `oregonator'.") +@{ + ColumnVector dx (3); + + ColumnVector x = args(0).vector_value (); + + dx(0) = 77.27 * (x(1) - x(0)*x(1) + x(0) + - 8.375e-06*pow (x(0), 2)); + + dx(1) = (x(2) - x(0)*x(1) - x(1)) / 77.27; + + dx(2) = 0.161*(x(0) - x(2)); + + return octave_value (dx); +@} +@end group +@end example + +The first line of the file, + +@example +#include <octave/oct.h> +@end example + +@noindent +includes declarations for all of Octave's internal functions that you +will need. If you need other functions from the standard C++ or C +libraries, you can include the necessary headers here. + +The next two lines +@example +@group +DEFUN_DLD (oregonator, args, , + "The `oregonator'.") +@end group +@end example + +@noindent +declares the function. The macro @code{DEFUN_DLD} and the macros that +it depends on are defined in the files @file{defun-dld.h}, +@file{defun.h}, and @file{defun-int.h} (these files are included in the +header file @file{octave/oct.h}). + +Note that the third parameter to @code{DEFUN_DLD} (@code{nargout}) is +not used, so it is omitted from the list of arguments to in order to +avoid the warning from gcc about an unused function parameter. + +@noindent +simply declares an object to store the right hand sides of the +differential equation, and + +The statement + +@example +ColumnVector x = args(0).vector_value (); +@end example + +@noindent +extracts a column vector from the input arguments. The variable +@code{args} is passed to functions defined with @code{DEFUN_DLD} as an +@code{octave_value_list} object, which includes methods for getting the +length of the list and extracting individual elements. + +In this example, we don't check for errors, but that is not difficult. +All of the Octave's built-in functions do some form of checking on their +arguments, so you can check the source code for those functions for +examples of various strategies for verifying that the correct number and +types of arguments have been supplied. + +The next statements + +@example +@group +ColumnVector dx (3); + +dx(0) = 77.27 * (x(1) - x(0)*x(1) + x(0) + - 8.375e-06*pow (x(0), 2)); + +dx(1) = (x(2) - x(0)*x(1) - x(1)) / 77.27; + +dx(2) = 0.161*(x(0) - x(2)); +@end group +@end example + +@noindent +define the right hand side of the differential equation. Finally, we +can return @code{dx}: + +@example +return octave_value (dx); +@end example + +@noindent +The actual return type is @code{octave_value_list}, but it is only +necessary to convert the return type to an @code{octave_value} because +there is a default constructor that can automatically create an object +of that type from an @code{octave_value} object, so we can just use that +instead. + +To use this file, your version of Octave must support dynamic linking. +To find out if it does, type the command +@kbd{octave_config_info ("dld")} at the Octave prompt. Support for +dynamic linking is included if this command returns 1. + +To compile the example file, type the command @samp{mkoctfile +oregonator.cc} at the shell prompt. The script @code{mkoctfile} should +have been installed along with Octave. Running it will create a file +called @file{oregonator.oct} that can be loaded by Octave. To test the +@file{oregonator.oct} file, start Octave and type the command + +@example +oregonator ([1, 2, 3], 0) +@end example + +@noindent +at the Octave prompt. Octave should respond by printing + +@example +@group +ans = + + 77.269353 + -0.012942 + -0.322000 +@end group +@end example + +You can now use the @file{oregonator.oct} file just as you would the +@code{oregonator.m} file to solve the set of differential equations. + +On a 133 MHz Pentium running Linux, Octave can solve the problem shown +in @ref{Ordinary Differential Equations} in about 1.4 second using the +dynamically linked function, compared to about 19 seconds using the +M-file. Similar decreases in execution time can be expected for other +functions, particularly those that rely on functions like @code{lsode} +that require user-supplied functions. + +Just as for M-files, Octave will automatically reload dynamically linked +functions when the files that define them are more recent than the last +time that the function was loaded. Two variables are available to +control how Octave behaves when dynamically linked functions are cleared +or reloaded. + +@defvr {Built-in Variable} auto_unload_dot_oct_files +If the value of @code{auto_unload_dot_oct_files} is nonzero, Octave will +automatically unload any @file{.oct} files when there are no longer any +functions in the symbol table that reference them. +@end defvr + +@defvr {Built-in Variable} warn_reload_forces_clear +If several functions have been loaded from the same file, Octave must +clear all the functions before any one of them can be reloaded. If +@code{warn_reload_forces_clear}, Octave will warn you when this happens, +and print a list of the additional functions that it is forced to clear. +@end defvr + +Additional examples for writing dynamically linked functions are +available in the files in the @file{src} directory of the Octave +distribution. Currently, this includes the files + +@example +@group +balance.cc fft2.cc inv.cc qzval.cc +chol.cc filter.cc log.cc schur.cc +colloc.cc find.cc lsode.cc sort.cc +dassl.cc fsolve.cc lu.cc svd.cc +det.cc givens.cc minmax.cc syl.cc +eig.cc hess.cc pinv.cc +expm.cc ifft.cc qr.cc +fft.cc ifft2.cc quad.cc +@end group +@end example + +@noindent +These files use the macro @code{DEFUN_DLD_BUILTIN} instead of +@code{DEFUN_DLD}. The difference between these two macros is just that +@code{DEFUN_DLD_BUILTIN} can define a built-in function that is not +dynamically loaded if the operating system does not support dynamic +linking. To define your own dynamically linked functions you should use +@code{DEFUN_DLD}. + +There is currently no detailed description of all the functions that you +can call in a built-in function. For the time being, you will have to +read the source code for Octave. + +@node Organization of Functions, , Dynamically Linked Functions, Functions and Scripts +@section Organization of Functions Distributed with Octave + +Many of Octave's standard functions are distributed as function files. +They are loosely organized by topic, in subdirectories of +@file{@var{octave-home}/lib/octave/@var{version}/m}, to make it easier +to find them. + +The following is a list of all the function file subdirectories, and the +types of functions you will find there. + +@table @file +@item audio +Functions for playing and recording sounds. + +@item control +Functions for design and simulation of automatic control systems. + +@item elfun +Elementary functions. + +@item general +Miscellaneous matrix manipulations, like @code{flipud}, @code{rot90}, +and @code{triu}, as well as other basic functions, like +@code{is_matrix}, @code{nargchk}, etc. + +@item image +Image processing tools. These functions require the X Window System. + +@item io +Input-ouput functions. + +@item linear-algebra +Functions for linear algebra. + +@item miscellaneous +Functions that don't really belong anywhere else. + +@item plot +A set of functions that implement the @sc{Matlab}-like plotting functions. + +@item polynomial +Functions for manipulating polynomials. + +@item set +Functions for creating and manipulating sets of unique values. + +@item signal +Functions for signal processing applications. + +@item specfun +Special functions. + +@item special-matrix +Functions that create special matrix forms. + +@item startup +Octave's system-wide startup file. + +@item statistics +Statistical functions. + +@item strings +Miscellaneous string-handling functions. + +@item time +Functions related to time keeping. +@end table