1

我在 MatLab 中为二分算法编写了代码。我基于教科书中给出的伪代码。到目前为止,该算法在我所有的问题上都运行良好,但是当我被要求在区间 [1,2] 上找到 f(x) = x - tan(x) 的根时,我遇到了一些麻烦。我的代码如下:

function x = bisection(a,b,M)
f = @(x) x - tan(x);
u = f(a);
v = f(b);
e = b-a;
x = [a, b, u, v]
if (u > 0 && v > 0) || (u < 0 && v < 0)
    return;
end;
for k = 1:M
    e = e/2;
    c = a + e;
    w = f(c);
    x = [k, c, w, e]
    if (abs(e) < 10^(-5) || abs(w) < eps)
        return;
    end
    if (w < 0 && u > 0) || (w > 0 && u < 0)
        b = c;
        v = w;
    else
        a = c;
        u = w;
    end
end

如果我在区间 [1,2] 上运行这个算法,比如 15 次迭代,我的最终答案是:

x =

  1.0e+004 *

    0.0015    0.0002   -3.8367    0.0000

这显然很遥远,因为我希望得到 f(c) = 0 (上面向量中的第三个条目)。

如果有人可以就如何提高我的成绩给我任何帮助/提示,​​我将不胜感激。我对 MatLab 很陌生,所以把我当作新手:)。

4

1 回答 1

4

我们来看看c二分法生成的序列:

c =  1.5000
c =  1.7500
c =  1.6250
c =  1.5625
c =  1.5938
c =  1.5781
c =  1.5703
c =  1.5742
c =  1.5723
c =  1.5713
c =  1.5708
c =  1.5706
c =  1.5707
c =  1.5707
c =  1.5708

你可以看到它收敛到pi/2。在这tan()一点上有一个奇点,所以也有x - tan(x)。例如,二分法收敛到这个奇点,如这里所说。这就是为什么函数值f(c)不接近于零的原因。事实上它应该去(加/减)无穷大。

其他建议:

我喜欢你的二分法。为了使其以更通用的方式使用,您可以合并以下更改:

  • 使变量f成为函数参数。然后,您可以将您的方法与不同的功能一起使用,而无需重新编写它。
  • 您第一次分配x = [a, b, u, v]但后来x(1)是迭代次数。我会让这更加一致。
  • 您可以通过查看产品的标志轻松测试是否f(a)有不同的标志。因为符号相等并且没有根,因为符号不同并且对于任何一个或为零,您已经找到了根。f(b)p = f(a)*f(b)p > 0p < 0p == 0f(a)f(b)
于 2012-08-03T19:20:40.370 回答