1. 程式人生 > >用牛頓方法解一元非線性方程的根(Matlab實現)

用牛頓方法解一元非線性方程的根(Matlab實現)

題目:用牛頓法求方程x-cos(x)=0的實根(精確到1E-6)。

(1)要求用函式呼叫。

(2)進一步研究和絃截法作比較。

演算法分析:

(1)       此題是利用牛頓方法解一元非線性方程的根。(牛頓法是把非線性方程區域性線性化的一種方法,它在單根附近具有較高的收斂速度。)所以首先我們應先給出估計的根,先對方程x-cos(x)=0變形,令y1=x,y2=cos(x),則兩函式圖象的交點,就是方程x-cos(x)=0的根,這裡利用Matlab作圖估計根的值。

在Matlab命令列中輸入,並執行:

>>x=-2:0.01:2;

>>y1=cos(x);

>>y2=x;

>>plot(x,y1,x,y2);

>>grid on;

可得下圖:


從圖中可以很容易得到根x的初值可選0.6。

(2)利用牛頓法的迭代公式x1=x0-(f(x0)/f’(x0));這裡首先取x0=0.6,代入迭代公式,然後判斷x1與x0之差的絕對值是否小於精度,如果小於精度,則停止,即得出根x的值,如果不小於精度,則繼續迭代,直到符合精度為止。

Matlab程式碼如下:

(1)funNewton.m函式檔案為:

%此檔案為被調函式檔案。
function[y,dirv_y]=funNewton(x)
%y與dirv_y為函式返回的引數,x為呼叫時的傳遞引數。
         y=x-cos(x);
         dirv_y=1+sin(x);
         %dirv_y為y的一階導函式


(2)Newton.m指令碼檔案為:

clear all
%清除所有變數
Error=1e-6;
%根所要求的誤差精度
formatlong
%格式化此行一下的變數。
x=0.6;
fork=1:20
%迭代次數20次
   [y,dirv_y]=funNewton(x);
   %呼叫函式檔案
   xk=x;
%xk可保留前一次x的值。
   x=x-y/dirv_y;
   %牛頓法的核心,即此迭代公式。
   if(abs(xk-x)<=Error)
%判斷當此x的值與前一次x的值即xk的差值,即誤差是否小於題目給定的誤差。
    break;
   end
end
x
%輸出根x的值。

 

在Matlab的命令列中輸入(因為我的程式檔案儲存為:Newton.m指令碼檔案,funNewton.m函式檔案):

>>Newton

x=0.739085133215161


結果分析:

在Matlab的命令列中輸入:

>>format long

>>fzero('x-cos(x)',0)

ans=0.739085133215161

經比較可知:牛頓法的結果有一定的誤差,但是牛頓方法由於在單根附近有良好的收斂性,所以與其他方法得出的結果相比誤差較小。但是牛頓方法有個缺點:它只在根附近區域性收斂。所以所我們在給定X的初值時尤為重要,如果給的初值離真值過遠。那麼用牛頓法可能永遠也找不到此方程的解。對於這種情況,我們可以先利用工具軟體(如:Matlab)畫出草圖,確定根的大致位置。牛頓法的每一步迭代都要計算一次導數值,而在計算機中,計算一次導數的近似值比計算函式值要麻煩的多。所以我們可以用弦截法,其迭代公式為:x2=x1-((x1-x0)/f(x1)-f(x0))*f(x1).

當f(x)在x*的某一個鄰域內具有二階連續導數,且f’(x)!=0,初值x0,x1落在此鄰域內,弦截

法是收斂的。

此文為本人原創!如需使用,請註明出處!