非线性方程的数值解法
一、实验目的 通 过 本 实 验的学习,应掌握 非线性方程的数值解法的 基本思想和原理,深刻认识 现 实 中 非 线 性 方 程 数 值的意义;明确代数精度的概念 ;熟悉几种基本的常用 的解非线性方 程 的 数 值 的 方 法 ,如二分法、迭代法 等,了解它 们各自的优缺点及适用范围,并能用来解决其他实 际 问 题 ; 熟 悉非线性方程的数值 的程序编制。
3. 实验的结果是存在一定的误差。
六、 实验中存在的问题及解决方案
1.在开始时,运用循环 for(k=1;k<(log(b-a)-log(0.000001))/log(2.0);k++) { c=(a+b)/2; if(fabs(function(c)<0.000001)) printf("k=%dx=%9.5f",k,c); else if(function(a)*function(c)<0) {d=c;c=b;b=d;} else {d=c;c=a;a=d;}}得到的结果是:
框图 1
二分法
框图 2
迭代法
2
南昌航空大学数学与信息科学学院实验报告
3.源程序代码: ①利用二分法的源程序如下: #include<stdio.h> #include<math.h> float function(float x); /*函数 f(x)的申明*/
main() { float root1(float x1,float x2); /*解得近似值函数的申明*/ float root2(float x1,float x2); /*解得近似值函数的申明*/ float a=-2,b=1,c1,c2; c1=root1(a,b); /*解得[-2,0]近似值函数的调用*/ c2=root2(a,b); /*解得[0,1]近似值函数的调用*/ printf("root is %10.6f\n%10.6f\n",c1,c2); /*输出结果*/ }float function(float x) { float y; y=pow(x,4)+2*pow(x,3)-x-1; return y; } float cmid(float x1,float x2) { float c; c=(x1+x2)/2; return (c); } float root1(float x1,float x2) { float cmid(float x1,float x2); float x,y,y1; do { x=cmid(x1,x2); y1=function(x1); y=function(x); if(y*y1<0) x2=x; else x1=x; }while(fabs(y)>=1e-6); return (x); } float root2(float x1,float x2) { float cmid(float x1,float x2); float x,y,y2; /*计算两个数的中值*/ /*函数 f(x)的定义*/
南昌航空大学
数学与信息科学学院
实 验 报 告
课程名称: 实验名称: 计 算 方 法 非线性方程的数值解法
实验类型: 验证性√ 综合性□ 设计性□ 实验室名称: 班级学号: 学生姓名: D 504 08061115 杨朝峰
任课教师(教师签名) : 成 绩: 2009-10-16
实验日期:
南昌航空大学数学与信息科学学院实验报告
二、实验题目 试计算方程发 f(x)=x 1. 2.
4
+2x -x+1=0 于[-2,1]的所有实根,要求
3
<10-6。
运用非线性方程数值解法的二分法解题。 运用非线性方程数值解法的迭代法解题
三、实验原理(包括所使用方法的原理、公式和程序框图)
1.原理: ①对于连续的函数 f(x),由罗尔中值定理广泛地推出利用含根区间[a,b]逐步分半,检 查函数值符号的变化,以便确定含根的充分小区间而得到二分法; ②用函数 f(x)构造出一个 x=g(x),再选取方程根的一个初始近似值 x0,按 xk+1=g(xk)逐 次代入法。 2.公式: 利用非线性方程的其中两种方法二分法以及迭代法。 3.程序框图: ①利用二分法的程序框图如框图 1: ②利用迭代法的程序框图如框图 2:
1
南昌航空大学数学与信息科学学院实验报告
输入初始值 x 输入区间 a,b 的值
K=1,2,…,N0
调用函数 root()
计算 xk+1
调用函数 cmit() 输出 x 是
<10-6
调用函数 function ()
X1←x
k≦100
否
<10
-6
输出没有达到精度 要求信息
成 立 输出 x 的值
输出没有数值信息
/*初值的选定*/
/ *用精度来作为循环结束的条件*/
南昌航空大学数学与信息科学学院实验报告
四、实验过程中需要记录的数据:
1. 实验中要记录迭代的次数 N0 和 k 的数值。 2. 在运行程序结束后要显示记录的两个实验的计算结果。
五、Байду номын сангаас实验数据处理及结果分析
1.在实验进行之前, 通过简单的计算知道实验 1 中的区间[-2,1]有两个实根, 其中一个为负实根, 另一个为正实根。但是运用二分法是无法之间求出两个不同的实根的,因此在编程的时候把区间化为 [-2,0]和[0,1]分别计算结果。 2.运用迭代法时,方程的真实根是无法确定的,即使知道精度也难以算出迭代的次数 N 数值,因 此认为的将 N 定义为 100 或者更大,只是运行时效率问题而已。 3 运行程序的结果如下:
经过分析知道程序的顺序有误,而且编程的思想错误,它的 f(a)*f(b)不小于 0,因此 我改变思想运用上述的源程序编译得到结果。
5
南昌航空大学数学与信息科学学院实验报告
2.运用迭代法解该方程时总会在 DOS 环境下报以下的错误:
其实运用迭代法时是有一定的局限性的, 即迭代法的局限收敛性。 如果初值选的不恰当 是得不到结果的,因此要在真实值附近取值。 3.在做迭代时开始选取 g(x)=x
6
4
+2x +1 为迭代函数时出现结果为
3
因此就选取牛顿—雷福生方法的公式作为迭代函数。 4.在做迭代法时一次无法同时输出两个值,所以选 x=0.7 和 x=-1.8 为初值。
七、 心得体会
通过本次编程, 在一定程度下了解并能基本掌握非线性方程的基本思想和 方法,了解 到 计 算 方 法 这 门课程能解决很多现实中难以解决的问题。通过 编程电脑实现很多现 实 理 论 不 能 解 决的问题。更加增加了学习的兴趣和动力。但在开始的时候因为自己 对 非 线 性 方 程 的思想不是十分清楚导致程序得不到答案甚至无法运行 程序,其实实 验 也 是 可 以 检 查我们对知识点的掌握程度。
/*解得[-2,0]近似值函数的定义*/
/*解得[0,1]近似值函数的定义*/
3
南昌航空大学数学与信息科学学院实验报告
do { x=cmid(x1,x2); y2=function(x2); y=function(x); if(y*y2<0) x1=x; else x2=x; }while(fabs(y)>=1e-6);/*用精度来作为循环结束的条件*/ return (x); ②利用迭代法的源程序如下: #include<stdio.h> #include<math.h> main() { float function(float x); float x1,x; int k; x1=0.7; for(k=1;k<1000;k++) { x= function(x1); if(fabs(x-x1)<1e-6) { printf("%10.6f\n",x); break; } else x1=x; } } float function(float x) { float y; y=x-(pow(x,4)+2*pow(x,3)-x-1)/(4*pow(x,3)+6*pow(x,2)-1); return y; } 4 /*利用牛顿法公式作为迭代函数的定义*/