我有一个功能
b=2.02478;
g=3.45581;
s=0.6;
R=1;
p =@(r) 1 - (b./r).^2 - (g^-2)*((2/15)*(s/R)^9 *(1./(r - 1).^9 - 1./(r + 1).^9 - 9./(8*r).*(1./(r - 1).^8 - 1./(r + 1).^8)) -(s/R)^3 *(1./(r-1).^3 - 1./(r+1).^3 - 3./(2*r).*(1./(r-1).^2 - 1./(r+1).^2)));
options = optimset('Display','off');
tic
r2 = fzero(p,[1.001,100])
toc
tic
r3 = fsolve(p,[1.001,100],options)
toc
和答案
r2 =
2.0198
Elapsed time is 0.002342 seconds.
r3 =
2.1648 2.2745
Elapsed time is 0.048991 seconds.
哪个更容易理解? fzero返回的值不同于fsolve
答案 0 :(得分:4)
您应该始终查看函数的exit标志(或输出结构),尤其是当您的结果不符合预期时。
这就是我得到的:
fzero(func,[1.00001,100])
:
X = 4.9969
FVAL
EXITFLAG = 1 % fzero found a zero X.
OUTPUT.message = 'Zero found in the interval [1.00001, 100]'
fzero(func,1.1)
:
X = 1
FVAL = 8.2304e+136
EXITFLAG = -5 % fzero may have converged to a singular point.
OUTPUT.message = 'Current point x may be near a singular point. The interval [0.975549, 1.188] reduced to the requested tolerance and the function changes sign in the interval, but f(x) increased in magnitude as the interval reduced.'
退出标志的含义在matlab文档中有解释:
1 Function converged to a solution x. -5 Algorithm might have converged to a singular point. -6 fzero did not detect a sign change.
因此,根据这些信息,很明显第一个信息可以为您提供正确的结果。
为什么fzero
失败
作为documented in the manual,fzero
通过查找符号更改来计算零:
尝试在
x
找到一个点fun(x) = 0
。此解决方案是fun(x)
更改sign-fzero无法找到x^2
等函数根的地方。
因此,X = 1
也是您的公式的解决方案,因为标志在此位置从+ inf变为-inf,如图中所示:
请注意,如果可能,提供搜索范围始终是一个好主意,如手册中所述:
以有限间隔调用
fzero
保证fzero
将在FUN
更改符号的位置附近返回值。提示:使用间隔(
fzero
使用两个元素)调用x0
通常比使用标量x0
调用它更快。
替代方案:fsolve
注意,该方法是为解决多个非线性方程组而开发的。因此,它不如fzero
有效(在你的情况下慢约20倍)。 fzero
使用基于渐变的方法(查看manual以获取更多信息),这可能在某些情况下效果更好,但可能会陷入局部极值。在这种情况下,只要初始值大于1,函数的梯度就会给出正确的方向。因此,对于此特定函数,fsolve
比具有单个初始值的fzero
更强大一些,即fsolve(func, 1.1)
返回预期值。
结论:一般情况下,fzero
使用搜索范围而不是初始值(如果可能的话)用于单个变量,fsolve
用于多个变量。如果一个方法失败,您可以尝试其他方法或另一个起点。
答案 1 :(得分:0)
正如您可以在文档中看到的那样:
该算法由T. Dekker发起,使用二分,割线和逆二次插值方法的组合。
因此,它对寻求解决方案的初始点和区域很敏感。因此,对于不同的初始值和范围,您得到了不同的结果。