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 (上記のベクトルの 3 番目のエントリ) を取得したいので、これは明らかに外れています。

誰かが私の結果を改善する方法について助けやヒントをくれれば、とても感謝しています. 私は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 に答える