Newsletters - MATLAB News & Notes
Functions As Parameters
Function handles add performance and control
by Mary Ann Branch and Peter Webb
MATLAB function handles allow you to efficiently pass functions as parameters to other functions. This is particularly useful for solving numerical optimization problems, where many of the solvers require you to provide them with a function to minimize. In previous versions of MATLAB, you pass functions as parameters by passing in the name of the function as a string. These function name strings are then passed to eval() or feval() to invoke the functions they represent. MATLAB 6 introduces function handles, a new data type that represents functions far more efficiently than strings do.
Increased performance and control
Function handles improve on function name strings in four areas:
Better performance. Function handles search the path only when they are created; eval() and feval() search the path every time they invoke a function name string.
More control. Function handles can refer to any function that is visible when they are created. You can create a handle to a subfunction or private function, for example, and pass
it into a context where that function would ordinarily not
be visible. Functions in that context can then invoke the subfunction or private function via the function handle.
Increased maintainability. Because you can create function handles to subfunctions, you no longer have to create a separate M-file for each function you want to pass to feval(). This is particularly useful for users of the Optimization Toolbox or MATLAB function functions; see
programming pattern #1 for more detail on this.
Compiler support. Function handles are much easier to compile than function name strings. The MATLAB Compiler supports function handles completely; most uses of eval() will likely remain unsupported.
![]() |
Minimizing the mypeaks function, shown as a surface here, is simplified using function handles. The call to the optimization function fminsearch can be combined with the mypeaks function into one file. |
Function handles are easy to use
You create a function handle using the new @ syntax:
function r = fibonacci(n)
if n == 0 | n == 1 r = 1;
else
r = fibonacci(n-1) + fibonacci(n-2);
end| Scalar Function Handle | Array of Function Handles |
|
|
To invoke a function handle, simply pass it to feval():
You cannot pass an array of function handles to feval()-it requires a single function handle argument. You create function handles by specifying the name of a function. But what happens when there is more than one function with that name on the MATLAB path? In that case, the function handle represents the list of all the functions with that name which you could possibly call from the current context. When you invoke the function handle with feval(), the arguments you supply determine which of the possible functions gets called.
In addition, function handles help you control the MATLAB function name space, by allowing you to create and call multiple functions that have the same name. This is explained more fully in programming pattern #2.
Programming pattern #1: Function functions
Some functions take functions as arguments. For example, MATLAB's ODE suite includes functions such as ode45, MATLAB itself contains a simplex minimization function fminsearch, and the Optimization Toolbox contains nonlinear programming solvers such as fmincon. When you set up a problem to solve and then call one of these solvers, you provide a MATLAB function to the solver that evaluates the function you want to minimize. It would be convenient to have the call to the optimization solver as well as the objective function all in the same file. This is now possible with function handles. Here is an M-file, minpeaks.m, that contains a function minpeaks and a subfunction mypeaks. minpeaks uses fminsearch to minimize the mypeaks function.
function [x0,f0,xout,fout]=minpeaks
% MINPEAKS minimize mypeaks function.
% create function handle to mypeaks subfunction
f = @mypeaks;
% start point
x0=[-0.35;-0.65];
% function value at start
f0 = feval(f,x0);
[xout,fout] = fminsearch(f,x0);
function z = mypeaks(x)
% MYPEAKS subfunction z
= 3*(1-x(1)).^2.*exp(-(x(1).^2)... - (x(2)+1).^2) - 10*(x(1)/5 - x(1).^3... - x(2).^5).*exp(-x(1).^2-x(2).^2)... - 1/3*exp(-(x(1)+1).^2 - x(2).^2);
Aside from the @ syntax, there is no special code required on the part of the person writing minpeaks.m. Also, no special code needs to be added to solvers such as fminsearch because feval works on function handles. Before function handles, the function mypeaks needed to be in a separate M-file so that it could be called from inside fminsearch.
Programming pattern #2: Working with overloaded functions
This example shows how you can work with multiple functions that have the same name at the same time using function handles. Suppose you have created a suite or library of functions in a directory library1. After a few months you come out with a second version of your library that you have in directory library2. You'd like to compare the same function in both versions of the library to make sure your answers are correct and your new library is faster.
Somewhere on your path, you have the following function LOADLIB:
function varargout = loadlib(dir, varargin)
% LOADLIB returns function handles from
% directory DIR.
% [FUN1,FUN2,...] = LOADLIB(DIR,FILE1,FILE2,...)
% creates function handles FUN1,FUN2, for files % FILE1,FILE2,... even if DIR is not on the path.
% put requested directory on front of path addpath(dir, 'begin')
% create array of function handles list = str2func(varargin);
% turn array into cell array varargout varargout = num2cell(list);
% clean up path rmpath(dir)
This function takes a version, such as library2, and a list of functions, given as string names, and returns function handles to the functions. For example, if you have functions fmin and ode in both libraries:
[fmin1, ode1]=loadlib('library1','fmin','ode'); [fmin2, ode2]=loadlib('library2','fmin','ode');
Now, although these functions have the same name, you can compare them without renaming them, changing the path, or changing the current working directory.
Say you want to time them:
tic,for i=1:500, x=feval(fmin1,objfun,x0);end,toc
tic,for i=1:500, x=feval(fmin2,objfun,x0);end,toc
Summary
Function handles significantly increase the control you have over the visibility of your functions. You can make subfunctions of one M-file callable from outside that M-file; this means you no longer have to organize your functions into M-files based on which functions need to be visible from the command line. In addition, because function handles offer better performance and are better supported by the MATLAB Compiler, we expect them to eventually replace most uses of function name strings in the future.
The examples in this article just scratch the surface of what's possible with function handles. Watch the newsgroup comp.soft-sys.matlab, the MATLAB Digest, and future editions of News & Notes for more techniques and information. ![]()
Store
