實驗名稱:方程求根
實驗目的和要求:
1.了解方程求根的基本方法、基本原理、誤差估計;
2.能夠按照工程實際要求,選擇適當的演算法;
3.通過編寫程式,進行演算法設計和數值求解。
實驗內容和原理:
1. 熟悉使用二分法、牛頓法等方程求根的基本方法、基本原理、誤差估計的相關理論。
2. 選擇方程求解方法中的兩種方法求方程:f(x)=x
3+4x
2-10=0在[1,2]內的乙個實根,且要求滿足精度|x*-x
n|<0.5×10-5。
如何對區間進行二分,並在二分後的左右兩個區間中確定下一次求根搜尋的區間?
假設區間端點為x1和x2,則通過計算區間的中點x0,即可將區間[x1, x2]二分為[x1, x0]和[x0, x2]。這時,為了確定下一次求根搜尋的區間,必須判斷方程的根在哪乙個區間內,由上圖可知方程的根所在區間的兩個端點處的函式值的符號一定是相反的。也就是說,如果f(x0)與f(x1)是異號的,則根一定在左區間[x1, x0]內,否則根一定在右區間[x0, x2]內。
牛頓迭代法計算公式
設r是f(x) = 0的根,選取x0作為r初始近似值,過點(x0,f(x0))做曲線y = f(x)的切線l,l的方程為y = f(x0)+f'(x0)(x-x0),求出l與x軸交點的橫座標 x1 = x0-f(x0)/f'(x0),稱x1為r的一次近似值。過點(x1,f(x1))做曲線y = f(x)的切線,並求該切線與x軸交點的橫座標 x2 = x1-f(x1)/f'(x1),稱x2為r的二次近似值。重複以上過程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f'(x(n)),稱為r的n+1次近似值,上式稱為牛頓迭代
公式。解非線性方程f(x)=0的牛頓法是把非線性方程線性化的一種近似方法。把f(x)在x0點附近展開成泰勒級數 f(x) = f(x0)+(x-x0)f'(x0)+(x-x0)^2*f''(x0)/2! +… 取其線性部分,作為非線性方程f(x) = 0的近似方程,即泰勒展開的前兩項,則有f(x0)+f'(x0)(x-x0)=0 設f'(x0)≠0則其解為x1=x0-f(x0)/f'(x0) 這樣,得到牛頓法的乙個迭代序列:x(n+1)=x(n)-f(x(n))/f'(x(n))。
主要儀器裝置:
電腦、win10、devc++執行環境
上機除錯修改源程式:
牛頓法:
#include
using namespace std;
#include
const double n=0.5*1e-5;
double get(double x);
double arry2[7]=;
double coefficient[7];
memset(coefficient,0,sizeof(double)*7);
vectorvx,vy;
for (int i=0; i<7; i++)
vx.push_back(arry1[i]);
vy.push_back(arry2[i]);
ematrix(vx,vy,7,3,coefficient);
printf("擬合方程為:y = %lf + %lfx + %lfx^2 \n",coefficient[1],coefficient[2],coefficient[3]);
return 0;
//累加
double sum(vectorvnum, int n)
double dsum=0;
for (int i=0; idsum+=vnum[i];
return dsum;
//乘積和
double mutilsum(vectorvx, vectorvy, int n)
double dmultisum=0;
for (int i=0; idmultisum+=vx[i]*vy[i];
return dmultisum;
//ex次方和
double relatepow(vectorvx, int n, int ex)
double resum=0;
for (int i=0; iresum+=pow(vx[i],ex);
return resum;
//x的ex次方與y的乘積的累加
double relatemutixy(vectorvx, vectorvy, int n, int ex)
double dremultisum=0;
for (int i=0; idremultisum+=pow(vx[i],ex)*vy[i];
return dremultisum;
//計算方程組的增廣矩陣
void ematrix(vectorvx, vectorvy, int n, int ex, double coefficient)
for (int i=1; i<=ex; i++)
for (int j=1; j<=ex; j++)
em[i][j]=relatepow(vx,n,i+j-2);
em[i][ex+1]=relatemutixy(vx,vy,n,i-1);
em[1][1]=n;
calequation(ex,coefficient);
//求解方程
void calequation(int exp, double coefficient)
for(int k=1;kfor(int i=k+1;idouble p1=0;
if(em[k][k]!=0)
p1=em[i][k]/em[k][k];
for(int j=k;jem[i][j]=em[i][j]-em[k][j]*p1;
coefficient[exp]=em[exp][exp+1]/em[exp][exp];
for(int l=exp-1;l>=1;l--) //回代求解
coefficient[l]=(em[l][exp+1]-f(coefficient,l+1,exp))/em[l][l];
//供calequation函式呼叫
double f(double c,int l,int m)
double sum=0;
for(int i=l;i<=m;i++)
sum+=em[l-1][i]*c[i];
return sum;
實驗結果與分析
討論、心得(可選):
程式設計不是一日練成的,需要每天堅持,這樣寫**才有感覺。編寫乙個大的系統往往很困難,但我們可以把它逐步細化、分解成乙個個小的模組,然後精細的設計每乙個小的模組,採用自頂向下,逐步細化的方法。遇到不懂的問題,查查等級高的部落格,往往會有新思路和高效的解法。c/c++中包含很多庫函式,不必要每個都記住,用的時候查詢stl就行了。
在程式設計中,和同學多多交流,會有意想不到的收穫,例如:兩種方法,會有更優的解決方案。
現在越來越體會到數值計算方法和我們的生活很貼近,非常方便有用。
數值計算方法實驗
1.給定下述演算法框圖,用逐步掃瞄法和二分法求方程x5 3x 1 0的最小正根,要求準確到1 2 10 2。要求 1 取步長h 1,先用逐步掃瞄法程式設計搜尋乙個隔根區間,將搜尋到的隔根區間列印輸出 2 然後對該區間使用二分法求方程的滿足精度要求的根,每二分一次,用新生成區間長度的一半作為是否二分結...
太原理工大學資料結構實驗報告
1.設有 n 個人圍坐在乙個圓桌周圍,現從第 s 個人開始報數,數到第 m 的人出列,然後從出列的下乙個人重新開始報數,數到 m 的人又出列,如此重複,直到所有的人全部出列為止。josephus 問題是 對於任意給定的 n,m,s,求出按出列次序得到的 n 個人員的順序表。include inclu...
武漢理工大學數值分析課內實驗
二 用c語言實現幾個求常微分方程初值問題解的程式。euler方法及其改進 龍格 庫塔 runge kutta 方法 三 用c語言實現幾個非線性方程求根的程式。二分法 迭代法 迭代過程的加速 四 用c語言實現幾個求線性方程組解的程式。gauss消去法 總結數值分析課內實驗採用程式設計的思想去實現有關數...