1. 程式人生 > >二分法 簡單迭代法 Newton法 弦截法 求解非線性方程的根

二分法 簡單迭代法 Newton法 弦截法 求解非線性方程的根

二分法 簡單迭代法  Newton法  弦截法 求解非線性方程的根

測試函式  為 f(x)=   sin(x); 

Code:
  1. #include <iostream>   
  2. #include <iomanip>   
  3. #include <cmath>   
  4. using namespace std;   
  5. double foofun(double x)//定義所要求解的函式表示式;   
  6. {   
  7.     double y;   
  8.     y=sin(x);//例項 用的函式 為 sin(x); 使用者可改為 其他的函式
      
  9.     return y;   
  10. }   
  11. double getCrossPoint(double x1,double x2)//定義求解弦與x軸的交點   
  12. {   
  13.     double y;   
  14.     y=(x1*foofun(x2)-x2*foofun(x1))/float((foofun(x2)-foofun(x2)));   
  15.     return y;   
  16. }   
  17. /************二分法定義************************/  
  18.  #define e 0.0005   
  19.  double dichotomy(double x1,double x2)   
  20.  {   
  21.      double x3;   
  22.      while (foofun(x1)*foofun(x2)<0)   
  23.      {   
  24.              /* if the x2 and x1 distance is less than e ,  
  25.               * then x1 or x2 can be recognise as a root of the equivalent  
  26.              */
      
  27.          while(fabs(x2-x1)<e)   
  28.          {   
  29.              /* Of course the average of x1 and x2 is also can be  
  30.               * regard as a root of the equivalent  
  31.              */  
  32.              cout<<"x1:"<<x1<<endl;   
  33.              cout<<"f(x1)= "<<foofun(x1)<<endl;   
  34.              cout<<"x2:"<<x2<<endl;   
  35.              cout<<"f(x2)= "<<foofun(x2)<<endl;   
  36.              cout<<"(x1+x2)/2:"<<(x1+x2)/2<<endl;   
  37.              cout<<"f((x1+x2)/2)= "<<foofun((x1+x2)/2)<<endl;//then display the x1 ,x2 ,(x1+x2)/2   
  38.              return (x1+x2)/2;   
  39.          }   
  40.          x3 = (x1+x2)/2;   
  41.          if(0 == foofun(x3))   
  42.          {   
  43.              cout<<"一個根為:x0: "<<x3 <<endl;   
  44.              cout<<"且f(x0) = 0"<<endl;   
  45.              return x3;   
  46.          }   
  47.          if(foofun(x1)*foofun(x3)>0)   
  48.          {   
  49.              x1=x3;   
  50.          }   
  51.          else  
  52.          {   
  53.              x2 = x3;   
  54.          }   
  55.      }   
  56.      cout<<"f(a) * f(b) >0";   
  57.  }   
  58. /*二分法定義**/  
  59. /************簡單迭代法************************/  
  60. // code :start here   
  61. float iter_foofun(float x)   
  62. {   
  63.    float x1,x2;   
  64.    x1 = x;   
  65.    x2 = foofun(x1);   
  66.    while(abs(x1-x2)>=e)   
  67.    {   
  68.        x1 = x2;   
  69.        x2 = foofun(x1);   
  70.    }   
  71.    return x2;   
  72. }   
  73. /*簡單迭代法**/  
  74. /***********Newton法解方程*********************/  
  75. double Dif_foofun(double x0)   
  76. {   
  77.     float y;   
  78.     y = cos(x0);   
  79.     return y;   
  80. }   
  81. double Newton_foo(double x0)   
  82. {   
  83.     double x, xx,f,f_dif;   
  84.     x = x0;   
  85.     f =foofun(x);   
  86.     f_dif=Dif_foofun(x);   
  87.     xx = x-f/f_dif;   
  88.     while((fabs(x-xx))>(1*10e-6))   
  89.     {   
  90.         x = xx;   
  91.         f = foofun(x);   
  92.         f_dif = Dif_foofun(x);   
  93.         xx = x -f/f_dif;   
  94.     }   
  95.     cout<<"方程的一個根的解為:"<<endl;   
  96.     cout<<xx<<endl;   
  97. }   
  98. /***********Newton法解方程end******************/  
  99. /************弦截法定義(begin************************/  
  100. double calEquationRoot(double x1,double x2)   
  101. {   
  102.     double x,y,y1;   
  103.     y1=foofun(x1);   
  104.     do  
  105.     {   
  106.         x=getCrossPoint(x1,x2);//呼叫求交點函式 x座標   
  107.         y=foofun(x);//求y座標   
  108.         if(y*y1 > 0)   
  109.         {   
  110.             y1 = y;   
  111.             x1 = x;   
  112.         }   
  113.         else  
  114.         {   
  115.             x2=x;   
  116.         }   
  117.     }while (fabs(y)>=0.00001);//fabs 求浮點數的 絕對值   
  118.     return x;   
  119. }   
  120. /************弦截法定義end************************/  
  121. void help()   
  122. {   
  123.     //cout<<" Define what you want do!/n";   
  124.     cout<<"*****Created by hsw******/n";   
  125.     cout<<"-------------------------/n";   
  126.     cout<<"  *1.二分法             **/n";   
  127.     cout<<"  *2.簡單迭代法         **/n";   
  128.     cout<<"  *3.Newton法           **/n";   
  129.     cout<<"  *4.弦截法             **/n";   
  130.     cout<<"  *0.退出               **/n";   
  131.     cout<<"-------------------------/n";   
  132. }   
  133. void seek()   
  134. {   
  135.   int flag;   
  136.   cout<<"請選擇你要進行的操作:";   
  137.   cin>>flag;   
  138.   while(0!=flag)   
  139.   {   
  140.       switch(flag)   
  141.       {   
  142.           case  1:   //二分法"   
  143.           {   
  144.               cout<<"你選擇的是:二分法"<<endl;   
  145.                cin.get();   
  146.                double a,b,f;   
  147.                cout<<"請輸入區間的上界a:"<<endl;   
  148.                cin>>a;   
  149.                cout<<"請輸入區間的下界b:"<<endl;   
  150.                cin>>b;   
  151.                f=dichotomy(a,b);   
  152.                cout<<"二分法求解方程的解為:x = "<<f<<endl;   
  153.           }   
  154.           flag = 0;   
  155.           seek();   
  156.           break;   
  157.           case  2:   //簡單迭代法   
  158.           {   
  159.                float x0;   
  160.                cout<<"你選擇的是:簡單迭代法"<<endl;   
  161.                cout<<"請輸入你所要選取初始值x0:/n"<<endl;   
  162.                cin >> x0;   
  163.                cout<<iter_foofun(x0)<<endl;   
  164.           }   
  165.           flag = 0;   
  166.           seek();   
  167.           break;   
  168.           case  3:    //Newton法   
  169.           {   
  170.               float x0;   
  171.               cout<<"你選擇的是:Newton法"<<endl;   
  172.               cout<<"請輸入你所要的選取的初始值x0:/n"<<endl;   
  173.               cin>>x0;   
  174.               Newton_foo(x0);   
  175.           }   
  176.           flag =0;   
  177.           seek();   
  178.           break;   
  179.           case  4:   //弦截法   
  180.           {   
  181.               cout<<"你選擇的是:弦截法"<<endl;   
  182.               double x1,x2,f1,f2,x;   
  183.               do //判斷輸入的弦x1,x2初值是否函式值相異   
  184.               {   
  185.                   cout<<"請輸入 x1,x2:";//如果同號 (根不在x1,x2 之間)   
  186.                   cin>>x1>>x2;        //則提示 再次輸入x1,x2;   
  187.                   f1 = foofun(x1);   
  188.                   f2 = foofun(x2);   
  189.               }while (f1*f2 >= 0);   
  190.               x=calEquationRoot(x1,x2);//這就話怎沒執行?怎沒改?   
  191.                                         //solution:顯示結果就可以了嗎,呵呵   
  192.               cout<<setiosflags(ios::fixed)<<setprecision(3);   
  193.               cout<<" One of the  Equation Root is: "<< x <<endl;   
  194.           }   
  195.           flag = 0;   
  196.           seek();   
  197.           break;   
  198.           default:   
  199.           cout<<"erro/n";   
  200.           seek();// 輸入錯誤 ,再次呼叫 seek 函式 提示使用者輸入選擇操作;   
  201.           break;   
  202.       }   
  203.   }   
  204.   return ;   
  205. }   
  206. int main()   
  207. {   
  208.     help();   
  209.     seek();   
  210.     //cout << "Hello world!" << endl;   
  211.     return 0;   
  212. }   

測試結果:

Code:
  1. 測試資料:   
  2. *****Created by hsw******   
  3. -------------------------   
  4.   *1.二分法             **   
  5.   *2.簡單迭代法         **   
  6.   *3.Newton法           **   
  7.   *4.弦截法             **   
  8.   *0.退出               **   
  9. -------------------------   
  10. 請選擇你要進行的操作:1   
  11. 你選擇的是:二分法   
  12. 請輸入區間的上界a:   
  13. -1   
  14. 請輸入區間的下界b:   
  15. 1   
  16. 一個根為:x0: 0   
  17. 且f(x0) = 0   
  18. 二分法求解方程的解為:x = 0   
  19. 請選擇你要進行的操作:2   
  20. 你選擇的是:簡單迭代法   
  21. 請輸入你所要選取初始值x0:   
  22. -1   
  23. -0.143633   
  24. 請選擇你要進行的操作:3   
  25. 你選擇的是:Newton法   
  26. 請輸入你所要的選取的初始值x0:   
  27. -1   
  28. 方程的一個根的解為:   
  29. 0   
  30. 你選擇的是:Newton法   
  31. 請輸入你所要的選取的初始值x0:   
  32. 4   
  33. 方程的一個根的解為:   
  34. 3.14159   
  35. 你選擇的是:Newton法   
  36. 請輸入你所要的選取的初始值x0: