1. 程式人生 > >【計算方法】實驗一 非線性方程求根數值解法

【計算方法】實驗一 非線性方程求根數值解法

實驗目的

(1)通過對二分法與牛頓迭代法做程式設計練習和上機運算,進一步體會二分法和牛頓法的不同。
(2)編寫割線迭代法的程式,求非線性方程的解,並於牛頓迭代法作比較。

實驗內容

1、用牛頓迭代法求下列方程的根
(1) x^2-e^x=0
(2) 〖xe〗^x-1=0
(3) lgx+x-2=0
2、編寫割線法程式求解第一問的方程

/* 牛頓迭代法的程式碼實現
 * 數值分析
 * 計科 1604 王宇晨 10430416414
 */

#include<iostream>
#include<string>
#include<cmath>
using
namespace std; const double e = 2.718281818284; const double eps = 1e-6; //求導數 X = x - f(x)/f'(x) double f1(double x){ double a = pow(e,x); return x-(x*x-a)/(2*x-a); } double f2(double x){ double a = pow(e,x); return x-(x*a-1)/(a*x+a); } double f3(double x){ double a = x*log(10); return
x-(log10(x) + x - 2)/( 1/a + 1); } void NewtonIterationMethod1(double x,double d){ double a = x; double b = f1(a); int k=0; //記錄迴圈的次數 while(((a-b)>d) || ((a-b)<-1*d)){ //cout<< a <<endl; a = b; b = f1(a); k ++; if(k>100){ cout
<<"迭代失敗!(函式不收斂)"<<endl; return ; } } cout<< b <<endl; return; } void NewtonIterationMethod2(double x,double d){ double a = x; double b = f2(a); int k=0; //記錄迴圈的次數 while(((a-b)>d) || ((a-b)<-1*d)){ //cout<< a <<endl; a = b; b = f2(a); k ++; if(k>100){ cout<<"迭代失敗!(函式不收斂)"<<endl; return ; } } cout<< b <<endl; return; } void NewtonIterationMethod3(double x,double d){ double a = x; double b = f3(a); int k=0; //記錄迴圈的次數 while(((a-b)>d) || ((a-b)<-1*d)){ //cout<< a <<endl; a = b; b = f3(a); k ++; if(k>100){ cout<<"迭代失敗!(函式不收斂)"<<endl; return ; } } cout<< b <<endl; return; } //二分法 double check1(double x){ double a = pow(e,x); return x*x-a; } double check2(double x){ double a = pow(e,x); return a*x - 1; } double check3(double x){ return log10(x) + x - 2; } void BinarySearch1(double d){ double st = -1000,ed = 1000; double mid = 0.0f; while(ed - st > d){ mid = st + (ed - st)/2; if(check1(mid) > 0){ st = mid; } else if(check1(mid) < 0){ ed = mid; } } cout<< mid <<endl; } void BinarySearch2(double d){ double st = -1000,ed = 1000; double mid = 0.0f; while(ed - st > d){ mid = st + (ed - st)/2; if(check2(mid) < 0){ st = mid; } else if(check2(mid) > 0){ ed = mid; } } cout<< mid <<endl; } void BinarySearch3(double d){ double st = -1000,ed = 1000; double mid = 0.0f; while(ed - st > d){ mid = st + (ed - st)/2; if(check3(mid) < 0){ st = mid; } else if(check3(mid) > 0){ ed = mid; } } cout<< mid <<endl; } int main(){ cout<< "請輸入初始值x0:"; double x,d = eps; cin>> x ; cout<< "牛頓迭代法" <<endl; NewtonIterationMethod1(x,d); NewtonIterationMethod2(x,d); NewtonIterationMethod3(x,d); cout<< "二分法" <<endl; BinarySearch1(d); BinarySearch2(d); BinarySearch3(d); return 0; }
#include<stdio.h>
#include<math.h>
#define eta 1e-6
//割線法
float ge(float(*f)(float),float x1,float x0)
{
    float x2,d;
    int k=0;
    do
    {
        k++;
        x2=x1-((*f)(x1)*(x1-x0))/((*f)(x1)-(*f)(x0));
        d=x1-x0;
        x0=x1;
        x1=x2;
        printf("x(%d)=%f\n",k,x0);
    }
    while(fabs(d)>eps&&fabs((*f)(x1))>eta);
    return x1;
}

float f(float x)   //第一問
{
    return x*x-exp(x);
}
float f1(float x)  //第二問
{
    return x*exp(x)-1;
}
float f2(float x)  //第三問
{
    return log10(x)+x-2;
}

int main()
{

    float x1,x0,y0,y1,y2;
    printf("please insert x1,x0\n");
    scanf("%f,%f",&x1,&x0);
    printf("x(0)=%f\n",x0);
    y0=ge(f,x1,x0);
    y1=ge(f1,x1,x0);
    y2=ge(f2,x1,x0);
    printf("one answer is %6f\n",y0);
    printf("two answer is %6f\n",y1);
    printf("three answer is %6f\n",y2);
    return 0;
}

實驗結果:
這裡寫圖片描述

這裡寫圖片描述