2017-02-21 7 views
2

私は非線形多項式関数を試しましたが、このコードはうまくいきます。しかし、これについては、バックスラッシュまたはbicgまたはlsqrを使って線形方程式df0 * X = f0を解くいくつかの方法を試みましたが、いくつかの初期値を試しましたが、結果は収束しません。非変換:ニュートンラフソン法を使って非線形方程式の根を見つける

% Define the given function 
syms x1 x2 x3 

x=[x1,x2,x3]; 

f(x)=[3*x1-cos(x2*x3)-1/2;x1^2+81*(x2+0.1)^2-sin(x3)+1.06;... 
    exp(-x1*x2)+20*x3+1/3*(10*pi-3)]; 

% Define the stopping criteria based on Nither or relative errors 

tol=10^-5; 
Niter=100; 

df=jacobian(f,x); 

x0=[0.1;0.1;-0.1]; 

% Setting starting values 

error=1; 
i=0; 

% Start the Newton-Raphson Iteration 

while(abs(error)>tol) 

f0=eval(f(x0(1),x0(2),x0(3))); 

df0=eval(df(x0(1),x0(2),x0(3))); 

xnew=x0-df0\f0; % also tried lsqr(df0,f0),bicg(df0,f0) 

error=norm(xnew-x0); 

x0=xnew; 

i=i+1 

if i>=Niter 

    fprintf('Iteration times spill over Niter\n'); 

    return; 

end 

end 
+0

関数をプロットし、開始推測のためのより良い選択を参照してください。 – duffymo

+0

関数は3つの方程式からなるベクトルです。どのようにプロットするのですか? – Jarvis

+0

なぜあなたはそこに 'eval'を使っていますか?それは完全に不要で、計算速度を損なうだけでなく、 'eval'とそれに関連する悪い習慣である深遠なピットにあなたを引き込むでしょう。 – Adriaan

答えて

1

ここでは、仕事をよりうまく行うために匿名機能が必要になります(今日はこれを説明しました)。

まず、関数定義をダウンさせましょう。匿名関数は、数学関数と同様の方法で物事を呼び出すための素晴らしい方法です。例えば、

f = @(x) x^2;

は二乗関数です。それを評価するには、あなたが紙のように書くだけでf(2)と言う。あなたのヤコビアンのために

f(x) = @(x) [3*x(1) - cos(x(2) * x(3)) - 1/2; ...

を、あなたは別の匿名関数を使用する必要があります(多分grad_fそれを呼び出す)と、それを計算します:あなたは、多変量の機能を持っているので、あなたは次のように定義をベクトル化する必要がありますそれでコード化してください。関数jacobianは有限差分を使用しているため、ヤコビ行列で積み重なるエラーは一部の地域では安定しません。

重要なのはちょっと注意して、良いコーディング方法を使用することです。匿名関数やその他の優れたMATLABの慣行については、this documentを参照してください。

+0

ありがとうございます! – Jarvis

+0

私はまだ質問がありますが、私が計算したf(x)の勾配はジャコビア関数の結果と同じです。また、私は最初の初めにループではなくジャコビアンを使用しました。 – Jarvis

関連する問題