二分法 簡單迭代法 Newton法 弦截法 求解非線性方程的根
阿新 • • 發佈:2018-12-26
二分法 簡單迭代法 Newton法 弦截法 求解非線性方程的根
測試函式 為 f(x)= sin(x);
Code:- #include <iostream>
- #include <iomanip>
- #include <cmath>
- using namespace std;
- double foofun(double x)//定義所要求解的函式表示式;
- {
- double y;
- y=sin(x);//例項 用的函式 為 sin(x); 使用者可改為 其他的函式
- return y;
- }
- double getCrossPoint(double x1,double x2)//定義求解弦與x軸的交點
- {
- double y;
- y=(x1*foofun(x2)-x2*foofun(x1))/float((foofun(x2)-foofun(x2)));
- return y;
- }
- /************二分法定義************************/
- #define e 0.0005
- double dichotomy(double x1,double x2)
- {
- double x3;
- while (foofun(x1)*foofun(x2)<0)
- {
- /* if the x2 and x1 distance is less than e ,
- * then x1 or x2 can be recognise as a root of the equivalent
- */
- while(fabs(x2-x1)<e)
- {
- /* Of course the average of x1 and x2 is also can be
- * regard as a root of the equivalent
- */
- cout<<"x1:"<<x1<<endl;
- cout<<"f(x1)= "<<foofun(x1)<<endl;
- cout<<"x2:"<<x2<<endl;
- cout<<"f(x2)= "<<foofun(x2)<<endl;
- cout<<"(x1+x2)/2:"<<(x1+x2)/2<<endl;
- cout<<"f((x1+x2)/2)= "<<foofun((x1+x2)/2)<<endl;//then display the x1 ,x2 ,(x1+x2)/2
- return (x1+x2)/2;
- }
- x3 = (x1+x2)/2;
- if(0 == foofun(x3))
- {
- cout<<"一個根為:x0: "<<x3 <<endl;
- cout<<"且f(x0) = 0"<<endl;
- return x3;
- }
- if(foofun(x1)*foofun(x3)>0)
- {
- x1=x3;
- }
- else
- {
- x2 = x3;
- }
- }
- cout<<"f(a) * f(b) >0";
- }
- /*二分法定義**/
- /************簡單迭代法************************/
- // code :start here
- float iter_foofun(float x)
- {
- float x1,x2;
- x1 = x;
- x2 = foofun(x1);
- while(abs(x1-x2)>=e)
- {
- x1 = x2;
- x2 = foofun(x1);
- }
- return x2;
- }
- /*簡單迭代法**/
- /***********Newton法解方程*********************/
- double Dif_foofun(double x0)
- {
- float y;
- y = cos(x0);
- return y;
- }
- double Newton_foo(double x0)
- {
- double x, xx,f,f_dif;
- x = x0;
- f =foofun(x);
- f_dif=Dif_foofun(x);
- xx = x-f/f_dif;
- while((fabs(x-xx))>(1*10e-6))
- {
- x = xx;
- f = foofun(x);
- f_dif = Dif_foofun(x);
- xx = x -f/f_dif;
- }
- cout<<"方程的一個根的解為:"<<endl;
- cout<<xx<<endl;
- }
- /***********Newton法解方程end******************/
- /************弦截法定義(begin************************/
- double calEquationRoot(double x1,double x2)
- {
- double x,y,y1;
- y1=foofun(x1);
- do
- {
- x=getCrossPoint(x1,x2);//呼叫求交點函式 x座標
- y=foofun(x);//求y座標
- if(y*y1 > 0)
- {
- y1 = y;
- x1 = x;
- }
- else
- {
- x2=x;
- }
- }while (fabs(y)>=0.00001);//fabs 求浮點數的 絕對值
- return x;
- }
- /************弦截法定義end************************/
- void help()
- {
- //cout<<" Define what you want do!/n";
- cout<<"*****Created by hsw******/n";
- cout<<"-------------------------/n";
- cout<<" *1.二分法 **/n";
- cout<<" *2.簡單迭代法 **/n";
- cout<<" *3.Newton法 **/n";
- cout<<" *4.弦截法 **/n";
- cout<<" *0.退出 **/n";
- cout<<"-------------------------/n";
- }
- void seek()
- {
- int flag;
- cout<<"請選擇你要進行的操作:";
- cin>>flag;
- while(0!=flag)
- {
- switch(flag)
- {
- case 1: //二分法"
- {
- cout<<"你選擇的是:二分法"<<endl;
- cin.get();
- double a,b,f;
- cout<<"請輸入區間的上界a:"<<endl;
- cin>>a;
- cout<<"請輸入區間的下界b:"<<endl;
- cin>>b;
- f=dichotomy(a,b);
- cout<<"二分法求解方程的解為:x = "<<f<<endl;
- }
- flag = 0;
- seek();
- break;
- case 2: //簡單迭代法
- {
- float x0;
- cout<<"你選擇的是:簡單迭代法"<<endl;
- cout<<"請輸入你所要選取初始值x0:/n"<<endl;
- cin >> x0;
- cout<<iter_foofun(x0)<<endl;
- }
- flag = 0;
- seek();
- break;
- case 3: //Newton法
- {
- float x0;
- cout<<"你選擇的是:Newton法"<<endl;
- cout<<"請輸入你所要的選取的初始值x0:/n"<<endl;
- cin>>x0;
- Newton_foo(x0);
- }
- flag =0;
- seek();
- break;
- case 4: //弦截法
- {
- cout<<"你選擇的是:弦截法"<<endl;
- double x1,x2,f1,f2,x;
- do //判斷輸入的弦x1,x2初值是否函式值相異
- {
- cout<<"請輸入 x1,x2:";//如果同號 (根不在x1,x2 之間)
- cin>>x1>>x2; //則提示 再次輸入x1,x2;
- f1 = foofun(x1);
- f2 = foofun(x2);
- }while (f1*f2 >= 0);
- x=calEquationRoot(x1,x2);//這就話怎沒執行?怎沒改?
- //solution:顯示結果就可以了嗎,呵呵
- cout<<setiosflags(ios::fixed)<<setprecision(3);
- cout<<" One of the Equation Root is: "<< x <<endl;
- }
- flag = 0;
- seek();
- break;
- default:
- cout<<"erro/n";
- seek();// 輸入錯誤 ,再次呼叫 seek 函式 提示使用者輸入選擇操作;
- break;
- }
- }
- return ;
- }
- int main()
- {
- help();
- seek();
- //cout << "Hello world!" << endl;
- return 0;
- }
測試結果:
Code:- 測試資料:
- *****Created by hsw******
- -------------------------
- *1.二分法 **
- *2.簡單迭代法 **
- *3.Newton法 **
- *4.弦截法 **
- *0.退出 **
- -------------------------
- 請選擇你要進行的操作:1
- 你選擇的是:二分法
- 請輸入區間的上界a:
- -1
- 請輸入區間的下界b:
- 1
- 一個根為:x0: 0
- 且f(x0) = 0
- 二分法求解方程的解為:x = 0
- 請選擇你要進行的操作:2
- 你選擇的是:簡單迭代法
- 請輸入你所要選取初始值x0:
- -1
- -0.143633
- 請選擇你要進行的操作:3
- 你選擇的是:Newton法
- 請輸入你所要的選取的初始值x0:
- -1
- 方程的一個根的解為:
- 0
- 你選擇的是:Newton法
- 請輸入你所要的選取的初始值x0:
- 4
- 方程的一個根的解為:
- 3.14159
- 你選擇的是:Newton法
- 請輸入你所要的選取的初始值x0: