Finding local extrema in Matlab and Octave via fminbnd()
I recently had to work on a Matlab assignment that required the use of
fminbnd() to find local extrema. As I typically work in Octave rather than Matlab I ran into some problems getting my code to work within both programmes. As it turned out, Matlab and Octave handle the function slightly differently, so I thought I'd share my findings to save others some headache.
First of all, some background information:
fminbnd() is a Matlab/Octave function to find a local minimum of a continuous function within a specified interval (check out this excellent page for a simple example). By default, the function is used like this:
[xval, yval, flag] = fminbnd(myfunction, startx, endx, options); This will search for local minima of the function
myfunction within the interval of
x = [startx, endx] and return the x-value of the minimum
xval, the corresponding y-value at the minimum
yval as well as an exit flag, which should be “1” if there is a solution. Although
fminbnd() is designed to search for minima, it can search for maxima by reversing the function parameter, i.e.
-myfunction. It's quite a handy function since it can greatly reduce the time required to determine the position of extrema when the rough location and type are already known.
The difficulty in getting
fminbnd() to work on Octave stemmed from the fact that the function in question required a large number of parameters and the way both programmes handle this syntactically. To illustrate the problem, have a look at the following piece of code:
function y = poly2(x,a,b) y = a*x.^2+b*x; end;
opts = optimset('Display','off'); [xval, yval, flag] = fminbnd('poly2',-2,2,opts,1,-2);
This apparently worked in Matlab, but didn't in Octave. The basic idea was to have Matlab iterate over the first parameter
x to find the local minimum, so in order to do that, the second and the third required parameters of
poly2() are appended in the call to
fminbnd(). Looking at the definition of
fminbnd() given above, it seems natural enough that this would fail, and Octave does indeed give an error:
error: Invalid call to fminbnd. Correct usage is: -- Function File: [X, FVAL, INFO, OUTPUT] = fminbnd (FUN, A, B, OPTIONS). The way to make this work in Octave is by using an anonymous function to define a wrapper which pre-defines the second and third parameter, so we get a new function that only requires one input parameter
poly2W = @(x) poly2(x,1,-2); [xval, yval, flag] = fminbnd(poly2W,-2,2,opts);
xval = 1.000000 yval = -1.000000 flag = 1. Defining
poly2W() in this way allows Octave to complete the search and determine the point (1,-1) as the minimum of the original function
a = 1 and
b = -2 within the interval
[-2,2]. The nice thing about anonymous functions is that they inherit arguments from the enclosing scope, so in case your parameter values are determined dynamically within the computation, you can simply call these variables when defining your anonymous function. The only downside that remains is that
fminbnd() appears to be considerably slower in Octave than in Matlab, but how much that matters depends on your project.