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 x
.
poly2W = @(x) poly2(x,1,-2);
[xval, yval, flag] = fminbnd(poly2W,-2,2,opts);
This gives 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 poly2()
for 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.