数值计算非线性方程的数值解法的C++程序

学数值计算方法写的实验程序,有各种解非线性方程的解法(二分法,简单迭代法,牛顿迭代法,弦截法等)的C++语言实现,还有调用gsl库函数的解法。要顺利编译需要安装并配置gsl库。编译方法(Ubuntu下): g++ nonline.cpp -o nonline -lm -lgsl -lgslcblas


//非线性方程的迭代解法
#include
#include
#include
#include
#include
#include
#include
//#include

using namespace std;

const double INF = 999999; //代表无限大

//定义方程的函数f(x)
double f(double x)
{
return x*x*x - x - 1.0;
}

//定义给gsl函数使用的函数gf(x,NULL)
double gf(double x, void * param)
{
return x*x*x - x - 1.0;
}

//定义迭代法的方程
double g(double x)
{
return pow((1.0+x), 1.0/3.0);
}

//定义牛顿迭代法用的函数f的导数
double df(double x)
{
return 2*x*x - 1;
}

//定义给gsl函数用的导函数dgf(x, NULL)
double dgf(double x, void * param)
{
return 2*x*x - 1;
}

//二分法解非线性方程
//输入参数:f-要解的的方程的表达式,a,b-为解的区间的上下界,eps-为容许误差
//x为结果,如果无解或出错,返回inf,函数返回bool值,如果求解成功返回true,
//否则返回false.
bool BinSolve(double (*fun)(double), double a, double b, double eps, double & x)
{
double m = 0.0;
int k = 0;
do
{
if (fun(a)*fun(b) > 0)
{
x = INF;
return false;
}
if (fun(a)*fun(b) == 0)
{
if (fun(a) == 0)
{
cout<<"找到解 a = "<if (k > N)
{
x = INF;
return false;
}
if (abs(f(x1)) < abs(f(x0)))
{
if (abs(x1 - x0) < eps)
{
x = x1;
return true;
}
x0 = x1;
continue;
}
else
{
if (lamda <= epsoflamda && abs(f(x1)) < eps)
{
x = x1;
return true;
}
else if (lamda <= epsoflamda && abs(f(x1)) >= eps)
{
x0 = x1 + 0.01;
continue;
}
else if (lamda > epsoflamda && abs(f(x1)) >= eps)
{
lamda = lamda/2.0;
continue;
}
}
}while(true);
return false;
}

//双点弦截法解非线性方程
//输入参数:f-要解的的方程的表达式,x0为迭代的初值,eps-为容许误差,
//N为允许最大迭代次数,x为结果,如果无解或出错,返回inf,函数返回bool值,
//如果求解成功返回true,否则返回false.
bool XianjieSolve(double (*f)(double), double x0,
double eps, int N, double & x)
{
double x1 = x0-0.1;
double x2 = 0.0;
double error = 0.0;
int k = 0;
do
{
x2 = x1 - (f(x1)*(x1 - x0))/(f(x1) - f(x0));
error = abs(x2-x1);
x0 = x1;
x1 = x2;
k++;
cout<<"第"<cin>>a;
cout<<"输入解的下界:";
cin>>b;
cout<<"输入允许误差:";
cin>>eps;
//判断输入
if (a >= b || eps <= 0)
{
cout<<"输入错误,程序将结束!\n";
exit(1);
}

cout.precision(30);
cout.width(35);

double x = 0.0;
//二分法
cout<<"二分法......\n";
if (BinSolve(f, a, b, eps, x) == true)
{
cout<<"方程在["<}
else
{
cout<<"方程在["<}
//简

单迭代法
cout<<"简单迭代法......\n";
//用求根区间的中点作为初值
if (DiedaiSolve(g, (a+b)/2, eps, N, x) == true)
{
cout<<"方程的解为:"<}
else
{
cout<<"方程无解"<}
//牛顿迭代法
cout<<"牛顿迭代法......\n";
//用求根区间的中点作为初值
if (NewtonSolve(f, df, (a+b)/2, eps, N, x) == true)
{
cout<<"方程的解为:"<}
else
{
cout<<"方程无解"<}
//牛顿下山迭代法
cout<<"牛顿下山迭代法......\n";
//用求根区间的中点作为初值
if (NewtonDownSolve(f, df, (a+b)/2, eps, N, x) == true)
{
cout<<"方程的解为:"<}
else
{
cout<<"方程无解"<}
//双点弦截法
cout<<"双点弦截法......\n";
//用求根区间的中点作为初值
if (XianjieSolve(f, (a+b)/2, eps, N, x) == true)
{
cout<<"方程的解为:"<}
else
{
cout<<"方程无解"<}
//调用gsl函数求解
cout<<"调用gsl函数求解......\n";
int status;
int iter = 0;
//二分法
//定义函数
gsl_function F;
F.function = &gf;
F.params = NULL;
//定义方程的解的结构
gsl_root_fsolver * s1 = gsl_root_fsolver_alloc(gsl_root_fsolver_bisection); //二分法
gsl_root_fsolver_set(s1, &F, a, b);
double r = 0.0;
double x_lo = 0.0, x_hi = 0.0;
do
{
iter++;
status = gsl_root_fsolver_iterate(s1);
r = gsl_root_fsolver_root(s1);
x_lo = gsl_root_fsolver_x_lower(s1);
x_hi = gsl_root_fsolver_x_upper(s1);
status = gsl_root_test_interval(x_lo, x_hi, 0, eps);

cout<<"第"<

相关文档
最新文档