Search code examples
matlabmatlab-figureminimization

fminbnd doesn't give the minimum value


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.


Solution

  • 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.