Newton-Raphson 法では正しくない点が 2 つありますが、確実に修正できます。これを修正した後VPA
、あなたが話しているエラーは必要ありません。
エラー #1 - 反復更新
最初のものは反復そのものです。Newton-Raphson 法の定義を思い出してください。

(ソース: mit.edu )
次の反復では、前の反復の値を使用します。あなたがしていることは、ループ カウンターを使用してこれを に代入していることですがf(x)
、これは正しくありません。これは、前の反復の値でなければなりません。
エラー #2 - 記号値と数値の混合
関数のコーディング方法を見ると、関数をシンボリックに定義しているにもかかわらず、数値を関数に代入しようとしています。残念ながら、これは MATLAB ではうまくいきません。実際に値を代入したい場合は、 を使用する必要がありますsubs
。x
これにより、関数として、または関数が使用している独立変数の実際の値が置き換えられます。これを行うと、値はまだsym
タイプです。これを数値的に使用できるようにするには、これをdoubleとしてキャストする必要があります。
y
また、効率のために、配列を作成する必要はありません。これを、反復ごとに更新される単一の値にするだけです。以上のことから、コードは次のように更新されます。念のために言っておきますが、必要な計算量を減らすために、ループの前に関数の導関数を取りました。また、ニュートン-ラフソン反復の分子項と分母項を分割して、物事を明確にし、これをsubs
. 難しい話は抜きにして:
function r = mynewton(f,a,n)
syms x;
z = f(x);
diffZ = diff(z); %// Edit - Include derivative
y = a; %// Initial root
for idx = 1 : n
numZ = subs(z,x,y); %// Numerator - Substitute f(x) for f(y)
denZ = subs(diffZ,x,y); %// Denominator - Substitute for f'(x) for f'(y)
y = y - double(numZ)/double(denZ); %// Update - Cast to double to get the numerical value
end
r = y; %// Send to output
end
ループ内で置き換えi
たことに注意してください。idx
その理由は、これらの文字が複素数を表すために予約されているため、ループ インデックスとしてi
orを使用することは実際には推奨されないためです。Shaij
によるこの投稿を見ると、これらの変数をループ インデックスとして使用する方が実際には遅いことがわかります: Using i and j as variables in Matlab
いずれにせよ、これをテストするために、関数がy = sin(x)
で、最初のルートが であると仮定しx0 = 2
、5 回の反復で次のようにします。
f = @(x) sin(x);
r = mynewton(f, 2, 5)
r =
3.1416
sin(x)
の切片は のsin(x)
整数倍の位置にあるため、これは の知識と一致しますpi
。 x0 = 2
は近くにあるpi
ため、これは期待どおりに機能します。
あなたのための小さなボーナス
元のコードには、 の各反復でルートの値が格納されていましたy
。本当にやりたい場合は、コードを次のように変更する必要があります。y
物事をより効率的にするために事前に割り当てたことに注意してください。
function r = mynewton(f,a,n)
syms x;
z = f(x);
diffZ = diff(z);
y = zeros(1,n+1); %// Pre-allocate output array
y(1) = a; %// First entry is the initial root
for idx = 1 : n
numZ = subs(z,x,y(idx)); %// Remember to use PREVIOUS guess for next guess
denZ = subs(diffZ,x,y(idx));
y(idx+1) = y(idx) - double(numZ)/double(denZ); %// Place next guess in right spot
end
r = y; %// Send to output
end
上記とまったく同じパラメーターを使用してこのコードを実行すると、次のようになります。
f = @(x) sin(x);
r = mynewton(f, 2, 5)
r =
2.0000 4.1850 2.4679 3.2662 3.1409 3.1416
の各値はr
、その特定の反復におけるルートの推測を示します。配列の最初の要素は、最初の推測です (もちろん)。次の値は、ニュートン ラフソン ルートの各反復での推測です。配列の最後の要素が最後の反復であることに注意してください。これはほぼ に等しいpi
です。