【計算方法】實驗一 非線性方程求根數值解法
阿新 • • 發佈:2019-01-10
實驗目的
(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;
}
實驗結果: