首先,fminbnd 返回函数最小位置的 x-coordinate。因此,实际最小值位于myFunction(0.7768)。 x=0.7768 是最小值所在的位置。
现在,我尝试使用更详细的信息运行您的代码。具体来说,我想看看每次迭代的最小变化。我覆盖了fminbnd 的默认设置,所以我们可以看到每次迭代发生了什么。
这是我得到的:
>> 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是最小值的位置,FVAL是最小值所在位置的y值,EXITFLAG=1表示算法收敛正确。
这显然不等于您想要的最小值。如果我可以参考fminbnd的文档,它具体是这样说的:
fminbnd may only give local solutions.
因此,您没有得到正确答案的原因是因为您的函数中有很多局部最小值。具体来说,如果您放大到x=0.7784,这本身就是一个局部最小值:
由于算法设法在这里找到了一个好的局部最小值,它决定停止。
如果您将函数的搜索边界限制在真正的最小值附近,我设法获得了真正的最小值。而不是 [-pi,pi]... 尝试类似 [-1,1] 的东西:
>> [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
当我这样做时,我设法获得了正确的最小位置和最小值本身。