Calling Octave Functions from Oct-Files - Untitled
Description: Untitled

Next: Calling External Code from Oct-Files, Previous: Accessing Global Variables in Oct-Files, Up: Oct-Files

#### A.1.8 Calling Octave Functions from Oct-Files

There is often a need to be able to call another octave function from within an oct-file, and there are many examples of such within octave itself. For example the `quad` function is an oct-file that calculates the definite integral by quadrature over a user supplied function.

There are also many ways in which a function might be passed. It might be passed as one of

1. Function Handle
2. Anonymous Function Handle
3. Inline Function
4. String

The example below demonstrates an example that accepts all four means of passing a function to an oct-file.

         /*

         Copyright (C) 2006, 2007 John W. Eaton

         This file is part of Octave.

         Octave is free software; you can redistribute it and/or
         modify it under the terms of the GNU General Public License
         as published by the Free Software Foundation; either
         version 3  of the License, or (at your option) any later
         version.

         Octave is distributed in the hope that it will be useful,
         but WITHOUT ANY WARRANTY; without even the implied warranty
         of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
         See the GNU General Public License for more details.

         You should have received a copy of the GNU General Public
         License along with Octave; see the file COPYING.  If not,
         see <http://www.gnu.org/licenses/>.

         */

         #include <octave/oct.h>
         #include <octave/parse.h>

         DEFUN_DLD (funcdemo, args, nargout, "Function Demo")
         {
           int nargin = args.length();
           octave_value_list retval;

           if (nargin < 2)
             print_usage ();
           else
             {
               octave_value_list newargs;
               for (octave_idx_type i = nargin - 1; i > 0; i--)
                 newargs (i - 1) = args(i);
               if (args(0).is_function_handle ()
                   || args(0).is_inline_function ())
                 {
                   octave_function *fcn = args(0).function_value ();
                   if (! error_state)
                     retval = feval (fcn, newargs, nargout);
                 }
               else if (args(0).is_string ())
                 {
                   std::string fcn = args (0).string_value ();
                   if (! error_state)
                     retval = feval (fcn, newargs, nargout);
                 }
               else
                 error ("funcdemo: expected string,",
         	       " inline or function handle");
             }
           return retval;
         }

The first argument to this demonstration is the user supplied function and the following arguments are all passed to the user function.

         funcdemo (@sin,1)
         => 0.84147
         funcdemo (@(x) sin(x), 1)
         => 0.84147
         funcdemo (inline ("sin(x)"), 1)
         => 0.84147
         funcdemo ("sin",1)
         => 0.84147
         funcdemo (@atan2, 1, 1)
         => 0.78540

When the user function is passed as a string, the treatment of the function is different. In some cases it is necessary to always have the user supplied function as an `octave_function` object. In that case the string argument can be used to create a temporary function like

         std::octave fcn_name = unique_symbol_name ("__fcn__");
         std::string fname = "function y = ";
         fname.append (fcn_name);
         fname.append ("(x) y = ");
         fcn = extract_function (args(0), "funcdemo", fcn_name,
                                 fname, "; endfunction");
         ...
         if (fcn_name.length ())
           clear_function (fcn_name);

There are two important things to know in this case. The number of input arguments to the user function is fixed, and in the above is a single argument, and secondly to avoid leaving the temporary function in the Octave symbol table it should be cleared after use.