Reputation: 2776
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)
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.
Upvotes: 4
Views: 1867
Reputation: 104565
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:
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.
Upvotes: 4
Reputation: 35525
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
Upvotes: 3