數值計算學習筆記(二)
介紹完誤差之後,必須說的就是二分法了。
圖片來自維基
(改了一下圖,知乎上傳png格式圖片背景竟然是黑色的。)
二分法很簡單,如上圖,已知 連續且 ,則方程 在 間至少有一個實根,那麼怎麼求它?
很簡單,取中間點 ,比較中間點的函數值和兩端點的值的乘積 ,說明這個區間中肯定有解。此時精確解 與 之間的差為 ,當這個值小於誤差 要求時, 就可以做為近似解。如果要求的精度越高(誤差越小),需要取得中間值個數越多,這個工作就是計算機的長項了。
太晚了今天,程序明天上。
—————————————
更新程序
function [x_star,k]=bisect1(fun,a,b,Tol)
fa=feval(fun,a); %這句代碼就相當於fa=fun(a)
fb=feval(fun,b); %這句代碼就相當於fb=fun(b)
k=1;
while abs(b-a)/2>Tol %當(b-a)/2的絕對值>Tol
x=(a+b)/2;
fx=feval(fun,x); %這句代碼就相當於fx=fun(x)
if fx*fa<0
b=x;
fb=fx;
else
a=x;
fa=fx;
end
k=k+1;
end
x_star=(a+b)/2;
x_star就是解
k是迭代次數
fun是要輸入的函數
(bisect是函數名稱,是bisection的簡寫;///bi-詞綴,前綴,「二」的意思,section「部分」,二分法。
Tol是誤差,是tolerance的簡寫)
這時候只要你想計算 在 之間的解,允許誤差為0.005,只需要在MATLAB的command line裡面輸入以下兩行代碼即可。
fun=inline(x^3-x-1);
[x_star,k]=bisect1(fun,1,1.5,0.005)
輸入完回車就會看到如下結果:
x_star =
1.3242
k =
7
即算出的計算值 ,計算了7次,取了7次中點。
————————————————
但是以上代碼只考慮了 的情況,但是如果輸入的函數在給定的區間端點恰好是 ,也就是說在給定的區間上不滿足二分法的求解條件。作為一個完整的程序需要考慮到這種情況。因此代碼添加如下一段:
if fa*fb>0
x_star=[fa,fb];
k=0;
return;
end
這是當你輸入
fun=inline(x^3-x-1);
[x_star,k]=bisect1(fun,1.4,1.5,0.005)
因為他在 上沒有根,所以他會輸出
x_star =
0.3440 0.8750
k =
0
輸出是和 處的值,告訴你他們兩個都大於0,計算了0次。
————————————————
此外,完整的代碼還應該考慮到,如果沒有要求誤差值為多少,應該設置一個較小的誤差默認值。即添加以下代碼:
if nargin<4
Tol=1e-5;
end
這段代碼的意思是,你可以只輸入
fun=inline(x^3-x-1);
[x_star,k]=bisect1(fun,1,1.5)
他會默認你的誤差為0.00001(1e-5),幫你算出在 之間的解。如下,MATLAB顯示:
x_star =
1.3247
k =
16
這時他運行了16次,取了16次中點,算出的值為1.3247,誤差為0.001%。
————————————————
因此完整的代碼為:
function [x_star,k]=bisect1(fun,a,b,Tol)
fa=feval(fun,a); %這句代碼就相當於fa=fun(a)
fb=feval(fun,b); %這句代碼就相當於fb=fun(b)
if nargin<4
Tol=1e-5;
end
if fa*fb>0
x_star=[fa,fb];
k=0;
return;
end
k=1;
while abs(b-a)/2>Tol %當(b-a)/2的絕對值>Tol
x=(a+b)/2;
fx=feval(fun,x); %這句代碼就相當於fx=fun(x)
if fx*fa<0
b=x;
fb=fx;
else
a=x;
fa=fx;
end
k=k+1;
end
x_star=(a+b)/2;
————————————————
已上考慮到一種情況就是,時不一定在區間無根,可能會存在重根的顯現。因此這就是牛頓法的弊端,所以會有迭代法的出現。
推薦閱讀: