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

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数值计算非线性方程的数值解法的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 = "<<a<<" a="<<a<<" b="<<b<<" k="<<k<<endl;<br>x = b;<br>}<br>return true;<br>}<br>else<br>{<br>m = (a+b)/2.0;<br>cout<<" m="<<m<<endl;<br>if (fun(a)*fun(m) > 0)<br>{<br>a = m;<br>}<br>else<br>{<br>b = m;<br>}<br>k++;<br>}<br>}while (abs(a-b) >= eps);<br>x = m;<br>return true;<br>}<br><br>//迭代法解非线性方程<br>//输入参数:f-要解的的方程的表达式,x0为迭代的初值,eps-为容许误差,N为允许最大迭代次数<br>//x为结果,如果无解或出错,返回inf,函数返回bool值,如果求解成功返回true,<br>//否则返回false.<br>bool DiedaiSolve(double (* fun)(double), double x0, double eps, long N, double & x)<br>{<br>double x1 = 0.0;<br>double error = 0.0;<br>int k = 0;<br>do<br>{<br>x1 = fun(x0);<br>error = abs(x1-x0);<br>k++;<br>cout<<" x(k+1)="<<x1<<endl;<br>x0 = x1;<br>if (k > N)<br>{<br>x = INF;<br>return false;<br>}<br>}while (error >= eps);<br>x =
x1;<br>return true;<br>}<br><br>//牛顿迭代法解非线性方程<br>//输入参数:f-要解的的方程的表达式,df-f的导数,x0为迭代的初值,eps-为容许误差,<br>//N为允许最大迭代次数,x为结果,如果无解或出错,返回inf,函数返回bool值,<br>//<br></p><!--/p1--><!--p2--><p>如果求解成功返回true,否则返回false.<br>bool NewtonSolve(double (*f)(double), double (*df)(double), double x0, <br>double eps, int N, double & x)<br>{<br>double x1 = 0.0;<br>double error = 0.0;<br>int k = 0;<br>do<br>{<br>x1 = x0 - f(x0)/df(x0);<br>error = abs(x1-x0);<br>x0 = x1;<br>k++;<br>cout<<" x["<<k<<"]="<<x1<<endl;<br>if (k > N)<br>{<br>x = INF;<br>return false;<br>}<br>}while (error >= eps);<br>x = x1;<br>return true;<br>}<br><br><br>//牛顿下山迭代法解非线性方程<br>//输入参数:f-要解的的方程的表达式,df-f的导数,x0为迭代的初值,eps-为容许误差,<br>//N为允许最大迭代次数,x为结果,如果无解或出错,返回inf,函数返回bool值,<br>//如果求解成功返回true,否则返回false.<br>bool NewtonDownSolve(double (*f)(double), double (*df)(double), double x0, <br>double eps, int N, double & x)<br>{<br>double lamda = 1; //下山因子<br>double x1 = 0.0;<br>double epsoflamda = 0.001;<br>int k = 0;<br>do<br>{<br>x1 = x0 - lamda*(f(x0)/df(x0));<br>k++;<br>cout<<" 下山因子为"<<lamda<<endl;
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<<"第"<<k<<"次迭代, x["<<k<<"]="<<x2<<endl;<br>if (k > N)<br>{<br>x = INF;<br>return false;<br>}<br>}while (error >= eps);<br>x = x2;<br>return true;<br>}<br><br>int main()<br>{<br>double a, b, eps;<br>const int N = 10000;<br>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<<"方程在["<<a<<","<<b<<"]区间内的解为:"<<x<<endl;
}
else
{
cout<<"方程在["<<a<<","<<b<<"]区间内无解"<<endl;
}
//简
</a<<","<<b<<"]区间内无解"<<endl;
</a<<","<<b<<"]区间内的解为:"<<x<<endl;
</k<<"次迭代,></a<<">
单迭代法
cout<<"简单迭代法......\n";
//用求根区间的中点作为初值
if (DiedaiSolve(g, (a+b)/2, eps, N, x) == true)
{
cout<<"方程的解为:"<<x<<endl;
}
else
{
cout<<"方程无解"<<endl;
}
//牛顿迭代法
cout<<"牛顿迭代法......\n";
//用求根区间的中点作为初值
if (NewtonSolve(f, df, (a+b)/2, eps, N, x) == true)
{
cout<<"方程的解为:"<<x<<endl;
}
else
{
cout<<"方程无解"<<endl;
}
//牛顿下山迭代法
cout<<"牛顿下山迭代法......\n";
//用求根区间的中点作为初值
if (NewtonDownSolve(f, df, (a+b)/2, eps, N, x) == true) {
cout<<"方程的解为:"<<x<<endl;
}
else
{
cout<<"方程无解"<<endl;
}
//双点弦截法
cout<<"双点弦截法......\n";
//用求根区间的中点作为初值
if (XianjieSolve(f, (a+b)/2, eps, N, x) == true)
{
cout<<"方程的解为:"<<x<<endl;
}
else
{
cout<<"方程无解"<<endl;
}
//调用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<<"第"<<iter<<"次迭代, relatedtopic"="" x["<<iter<<"]="<<r<<endl;<br>}while (status == GSL_CONTINUE && iter < N);<br>//释放解的结构<br>gsl_root_fsolver_free(s1);<br><br>return
0;<br>}<br><br></p><!--/p3--> </div> </div> <div> <div>相关文档</div> <div class=">
•非线性方程的数值解法
•数值计算方法实验程序
•数值计算方法实验
•线性方程组的数值解法
•数值计算方法实验报告
•(第2章非线性方程与方程组的数值解法)
•数值分析第7章非线性方程的数值解法
•非线性方程组数值解法
•第二章-一元非线性方程的数值解法
•非线性方程的数值解法
•第2章非线性方程的数值解法
•计算方法:非线性方程迭代求解.
•非线性方程的数值解法
•数值分析1非线性方程数值解法
•数值分析-非线性方程的数值解法
•非线性方程的数值解法
•非线性方程(组)的数值解法讲解
•第4章非线性方程数值解法
•非线性方程组求解及matlab实现分解
•最新8 非线性方程与方程组的数值解法_图文.ppt
•非线性薛定谔方程数值解的MATLAB仿真
•非线性方程组数值解法
•非线性方程的数值解法习题解答
•非线性方程的数值解法习题解答
•基于matlab的非线性方程组求解的方法
•更多"非线性方程的数值解法"
•数值分析MATLAB实验程序
•数值计算实验课题目
•太原理工大学数值计算方法实验报告
•数值计算方法实验5
•数值分析实验报告1
•《数值计算方法》上机实验报告
•数值计算方法实验报告
•数值分析实验报告
•数值计算方法实验3
•丁丽娟《数值计算方法》五章课后实验题答案(源程序很详细,且运行无误)
•数值计算方法实验报告
•《数值计算方法》上机实验报告
•数值计算方法实验指导(Matlab版)
•数值计算方法上机实验报告
•数值计算方法实验报告(含所有)
•数值计算方法实验一
•数值计算方法实验2
•数值计算方法实验程序
•数值分析实验指导书(2015)
•曲线拟合的数值计算方法实验
•更多"数值计算方法实验程序"
•曲线拟合的数值计算方法实验
•数值分析实验报告1
•(完整版)数值计算方法上机实习题答案
•数值分析实验报告总结
•数值分析计算方法实验报告
•数值分析实验报告-Sor法分析
•数值计算方法实验报告(例)讲解
•《数值计算方法》实验 (1)
•数值计算方法实验报告
•数值计算方法第3、4次实验--龙贝格--龙格库塔•数值分析计算方法
•数值分析验证性实验报告册2009.1.2
•数值计算方法实验1
•数值计算方法实验报告例
•线性方程组AX=B的数值计算方法实验
•数值分析实验报告(插值法)
•数值计算方法实验
•数值计算方法实验报告
•《数值计算方法》实验大纲
•数值计算方法上机实习题
•更多"数值计算方法实验"
•第二章线性方程组的数值解法
•线性方程组的数值解法实验
•0111 第六章线性方程组的数值解法
•线性方程组求解的数值方法
•数值2线性方程组与矩阵特征值求解的数值方法资料•MATLAB计算方法3解线性方程组计算解法
•数学计算方法线性方程组解法
•线性方程组AX=B的数值解法(j)PPT精选文档
•线性方程组数值解法总结
•线性方程组的直接解法实验报告
•线性方程组的数值解法
•数值分析-线性方程组的直接解法
•计算方法实验报告-线性方程组的数值解法
•计算方法线性方程组的数值解法
•第一章常用数值分析方法2 线性方程组的数值解法.ppt •线性方程组的数值解法及其应用
•数值计算方法 (第3章解线性方程组的数值解法)1
•线性方程组的数值解法
•数值分析解线性方程组的直接方法 ppt课件
•数值分析讲义——线性方程组的解法
•更多"线性方程组的数值解法"
•数值计算实验报告
•太原理工大学数值计算方法实验报告
•(完整版)哈工大-数值分析上机实验报告
•数值分析实验报告1
•数值分析实验报告
•数值分析实验报告一
•数值分析实验报告
•数值分析实验报告(插值法)
•数值分析实验报告5篇
•计算机数值计算方法实验报告
•数值计算方法与算法实验报告——误差
•数值分析实验报告总结
•数值分析实验报告(Matlab实现)
•数值计算方法实验报告模板
•数值分析实验报告
•数值计算方法实验报告6—数值微分
•数值计算方法实验报告
•数值计算方法实验报告
•哈工大数值分析报告上机实验报告材料
•数值分析实验报告
•更多"数值计算方法实验报告" </iter<<"次迭代,></endl; </x<<endl;
</endl;
</x<<endl;
</endl;
</x<<endl;
</endl;
</x<<endl;。

相关文档
最新文档