【问题标题】:fzero or fsolve ? differents results - Who is the correct ?fzero 还是 fsolve ?不同的结果 - 谁是正确的?
【发布时间】:2017-07-06 01:16:08
【问题描述】:

我有一个函数

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 不同的值

【问题讨论】:

  • 我不明白你的参数符号,你能编辑澄清一下
  • 参数 b 可以是从 0 开始到 10 结束的任意数字。例如,b= 1.5 和 g = 1 ..

标签: matlab precision


【解决方案1】:

您应该始终查看函数的退出标志(或输出结构),尤其是当您的结果与预期不符时。

这是我得到的:

  • 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 manualfzero 通过查找符号变化来计算零:

尝试找到fun(x) = 0 所在的点x。此解决方案是 fun(x) 更改符号的地方 - fzero 无法找到函数的根,例如 x^2

因此,X = 1 也是您的公式的解决方案,因为该位置的符号从 +inf 变为 -inf,如图所示:

请注意,如果可能,最好按照手册中的说明提供搜索范围:

以有限间隔调用fzero 保证fzero 将返回一个靠近FUN 更改符号的点的值。

提示:使用间隔调用fzero(使用两个元素的x0)通常比使用标量x0调用更快。

替代方案:fsolve

请注意,此方法是为求解多个非线性方程组而开发的。因此,它不如fzero 高效(在您的情况下慢约 20 倍)。 fzero 使用基于梯度的方法(有关更多信息,请查看 manual),这在某些情况下可能效果更好,但可能会陷入局部极值。在这种情况下,只要初始值大于 1,函数的梯度就会给出正确的方向。因此,对于这个特定的函数,fsolve 比具有单个初始值的fzero 更健壮,即@987654350 @ 返回预期值。

结论:一般情况下,如果可能,对单个变量使用fzero,而不是初始值,对多个变量使用fsolve。如果一种方法失败,您可以尝试另一种方法或另一个起点。

【讨论】:

  • 我可以用别的东西吗? fsolve,findroot,是不是比 fzero 好?
  • fsolve 也可以工作,并且适合您的情况(请参阅我编辑的答案)。我不知道findroot
  • 请注意,我只提供了一些通用规则,为了全面了解您应该深入了解底层算法。 fsolvefzero 的引用可能是一个很好的起点。
  • 我编辑了我的代码并将其全部放入我的整个程序中并讲述了我的问题。 r_min的起点改变I_value的值问题。如果您有时间这样做,请尝试测试并查看问题所在。
  • 啊好吧...如果你有时间看我的代码,我会很感激..它是给我的博士的..
【解决方案2】:

您可以在文档中阅读:

该算法由 T. Dekker 提出,结合使用二等分法、割线法和逆二次插值法。

因此,它对寻求解决方案的初始点和区域很敏感。因此,对于不同的初始值和范围,您会得到不同的结果。

【讨论】:

  • 我编辑了我的代码并将其全部放入我的整个程序中并讲述了我的问题。 r_min的起点改变I_value的值问题。如果您有时间这样做,请尝试测试并查看问题所在。
  • stackoverflow.com/questions/44894347/… 我的问题 - 已编辑 .. 感谢您的宝贵时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多