fzero 还是 fsolve?不同的结果 - 谁是正确的?
fzero or fsolve ? differents results - Who is the correct ?
我有一个功能
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 returns 与 fsolve
不同的值
您应该始终查看函数的退出标志(或输出结构),尤其是当您的结果不符合预期时。
这是我得到的:
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
通过寻找符号变化来计算零:
tries to find a point x
where fun(x) = 0
. This solution is where fun(x)
changes sign—fzero cannot find a root of a function such as x^2
.
因此,X = 1
也是您公式的解,因为符号在此位置从 +inf 变为 -inf,如绘图所示:
请注意,如手册所述,尽可能提供搜索范围总是一个好主意:
Calling fzero
with a finite interval guarantees fzero
will return a value near a point where FUN
changes sign.
Tip: Calling fzero
with an interval (x0
with two elements) is often faster than calling it with a scalar x0
.
替代:fsolve
请注意,此方法是为求解多个非线性方程组而开发的。因此,它不如 fzero
有效(在您的情况下慢 20 倍)。 fzero
使用基于梯度的方法(查看 manual 了解更多信息),这在某些情况下可能效果更好,但可能会陷入局部极值。在这种情况下,只要初始值大于 1,函数的梯度就会给出正确的方向。因此,对于此特定函数,fsolve
比具有单个初始值的 fzero
更稳健,即 fsolve(func, 1.1)
returns 预期值。
结论:一般情况下,单个变量尽可能使用fzero
搜索范围而不是初始值,多个变量尽可能使用fsolve
.如果一种方法失败,您可以尝试另一种方法或其他起点。
如您在文档中所见:
The algorithm, which was originated by T. Dekker, uses a combination of bisection, secant, and inverse quadratic interpolation methods.
因此,它对求解的初始点和区域很敏感。因此,对于不同的初始值和范围,您会得到不同的结果。
我有一个功能
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 returns 与 fsolve
不同的值您应该始终查看函数的退出标志(或输出结构),尤其是当您的结果不符合预期时。
这是我得到的:
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
通过寻找符号变化来计算零:
tries to find a point
x
wherefun(x) = 0
. This solution is wherefun(x)
changes sign—fzero cannot find a root of a function such asx^2
.
因此,X = 1
也是您公式的解,因为符号在此位置从 +inf 变为 -inf,如绘图所示:
请注意,如手册所述,尽可能提供搜索范围总是一个好主意:
Calling
fzero
with a finite interval guaranteesfzero
will return a value near a point whereFUN
changes sign.Tip: Calling
fzero
with an interval (x0
with two elements) is often faster than calling it with a scalarx0
.
替代:fsolve
请注意,此方法是为求解多个非线性方程组而开发的。因此,它不如 fzero
有效(在您的情况下慢 20 倍)。 fzero
使用基于梯度的方法(查看 manual 了解更多信息),这在某些情况下可能效果更好,但可能会陷入局部极值。在这种情况下,只要初始值大于 1,函数的梯度就会给出正确的方向。因此,对于此特定函数,fsolve
比具有单个初始值的 fzero
更稳健,即 fsolve(func, 1.1)
returns 预期值。
结论:一般情况下,单个变量尽可能使用fzero
搜索范围而不是初始值,多个变量尽可能使用fsolve
.如果一种方法失败,您可以尝试另一种方法或其他起点。
如您在文档中所见:
The algorithm, which was originated by T. Dekker, uses a combination of bisection, secant, and inverse quadratic interpolation methods.
因此,它对求解的初始点和区域很敏感。因此,对于不同的初始值和范围,您会得到不同的结果。