3

I'm trying some built-in functions in MATLAB. I declared a function like this:

function y = myFunction(x)
    y = cos(4*x) .* sin(10*x) .* exp(-abs(x));
end

Then I use fminbnd to find the minimum value:

fminbnd(@myFunction,-pi,pi)

This gives me the result:

ans =

0.7768

However, when I plot 'myFunction' in [-pi,pi], I got the following figure with this code that I used:

>> x = -pi:0.01:pi;
>> y = myFunction(x);
>> plot(x,y)

enter image description here

It can be seen that the min value is -0.77, which is not the result given by fminbnd. What's wrong here? I'm new to MATLAB and I don't know where I'm wrong.

rayryeng
  • 96,704
  • 21
  • 166
  • 177
lenhhoxung
  • 2,118
  • 2
  • 23
  • 49
  • 1
    First thing! The minimum is in -0.12. When you look for a minimum you dont look for the minimum value of the function but for the place where that minimum happens. so minimum -0.12, x=-0.12! – Ander Biguri Sep 30 '15 at 16:33
  • ah, so it's the position of x, thanks – lenhhoxung Sep 30 '15 at 16:45

2 Answers2

4

First things first, fminbnd returns the x-coordinate of the minimum location of your function. As such, the actual minimum is located at myFunction(0.7768). x=0.7768 is the location of where the minimum is.

Now, I tried running your code with more verbose information. Specifically, I wanted to see how the minimum changes at each iteration. I overrode the default settings of fminbnd so we can see what's happening at each iteration.

This is what I get:

>> y = @(x) cos(4*x).*sin(10*x).*exp(-abs(x)); %// No need for function declaration
>> options = optimset('Display', 'iter');
>> [X,FVAL,EXITFLAG] = fminbnd(y, -pi, pi, options)

 Func-count     x          f(x)         Procedure
    1      -0.741629      0.42484        initial
    2       0.741629     -0.42484        golden
    3        1.65833    -0.137356        golden
    4       0.775457    -0.457857        parabolic
    5        1.09264     0.112139        parabolic
    6       0.896609    -0.163049        golden
    7       0.780727    -0.457493        parabolic
    8         0.7768    -0.457905        parabolic
    9       0.776766    -0.457905        parabolic
   10       0.776833    -0.457905        parabolic

Optimization terminated:
 the current x satisfies the termination criteria using OPTIONS.TolX of 1.000000e-04 


X =

         0.776799595407872


FVAL =

        -0.457905463395071


EXITFLAG =

     1

X is the location of the minimum, FVAL is the y value of where the minimum is and EXITFLAG=1 means that the algorithm converged properly.


This obviously is not equal to your desired minimum. If I can reference the documentation of fminbnd, it specifically says this:

fminbnd may only give local solutions.

Going with that, the reason why you aren't getting the right answer is because you have a lot of local minima in your function. Specifically, if you zoom in to x=0.7784 this itself is a local minimum:

enter image description here

Since the algorithm managed to find a good local minimum here, it decides to stop.
I managed to get the true minimum if you restrict the search boundaries of the function to be around where the true minimum is. Instead of [-pi,pi]... try something like [-1,1] instead:

>> [X,FVAL,EXITFLAG] = fminbnd(y, -1, 1, options)


 Func-count     x          f(x)         Procedure
    1      -0.236068    -0.325949        initial
    2       0.236068     0.325949        golden
    3      -0.527864    -0.256217        golden
    4       -0.32561    0.0218758        parabolic
    5     -0.0557281    -0.487837        golden
    6      0.0557281     0.487837        golden
    7      -0.124612    -0.734908        golden
    8      -0.134743    -0.731415        parabolic
    9      -0.126213    -0.735006        parabolic
   10      -0.126055    -0.735007        parabolic
   11      -0.126022    -0.735007        parabolic
   12      -0.126089    -0.735007        parabolic

Optimization terminated:
 the current x satisfies the termination criteria using OPTIONS.TolX of 1.000000e-04 


X =

        -0.126055418940111


FVAL =

        -0.735007134768142


EXITFLAG =

     1

When I did this, I managed to the get the right minimum location and the minimum itself.

rayryeng
  • 96,704
  • 21
  • 166
  • 177
3

While this is only a partial answer I will just point out the following text that is in the Limitations section of the documentation of fminbnd:

fminbnd may only give local solutions.

Which is what is happening in your case. Often, when there is a function with multiple minima* optimization algorithms cant find the global minimum.

Generally the best approach when there are lots of minima is to split the function in 2, compute the minimum of both parts and then compare to see which one is smaller.

*you can find if you function has multiple minima by computing the derivative and checking the amount of zero crosses of the derivative and dividing by two

Ander Biguri
  • 32,737
  • 10
  • 68
  • 106