1、计算方法实验报告汇总 中 南 林 业 科 技 大 学计算机与信息工程学院数值分析实 验 报 告 姓名: 尹一君 _学号: 20134651 指导老师: 赵红敏 专业班级: 计算机科学与技术2班 指导教师评语: 成绩:签名: 年 月 日实验一 算法设计基础 - 2 -实验二 非线性方程求根 - 6 -实验三 线性方程组的直接解法 - 13 -实验四 解线性方程组的迭代法 - 21 -实验五 函数插值方法 - 27 -实验六 函数逼近与曲线拟合 - 31 -实验七 数值积分与数值微分 - 36 -参考文献 - 42 -实验一 算法设计基础1问题提出 编程实现以下矩阵相乘:2要求 1.编织一个程序进
2、行运算,最后打印出结果; 2.将编程结果与手工演算结果进行比较; 3.原始数据使用ASCII码数据文件的形式访问; 4.最好能将程序结果输出到ASCII码数据文件。3实验目的和意义 1.通过实验进一步熟悉矩阵运算和多重循环编程; 2.熟悉数据文件访问操作。四计算公式 在计算机中,一个矩阵实际上就是一个二维数组。一个m行n列的矩阵与一个n行p列的矩阵可以相乘,得到的结果是一个m行p列的矩阵,其中的第i行第j列位置上的数为第一个矩阵第i行上的n个数与第二个矩阵第j列上的n个数对应相乘后所得的n个乘积之和。五结构程序设计1.#define M 4#define N 3#define L 3#incl
3、udestdio.hvoid main() FILE *f; float AML,BLN,CMN; int i,j,k; if(f=fopen(Array1.txt,r)=NULL) return; for(i=0;iM;i+) for(j=0;jL;j+) fscanf(f,%f,&Aij); for(i=0;iL;i+) for(j=0;jN;j+) fscanf(f,%f,&Bij); for(i=0;iM;i+) for(j=0;jN;j+) Cij=0; for(k=0;kL;k+) Cij=Cij+Aik*Bkj; printf(%10.2f,Cij); printf(n); 2.
4、#define M 2#define N 3#define L 4#includestdio.hvoid main() FILE *f1; int AML,BLN,CMN; int i,j,k; if(f1=fopen(Array2.txt,r)=NULL) return; for(i=0;iM;i+) for(j=0;jL;j+) fscanf(f1,%d,&Aij); for(i=0;iL;i+) for(j=0;jN;j+) fscanf(f1,%d,&Bij); for(i=0;iM;i+) for(j=0;jN;j+) Cij=0; for(k=0;kL;k+) Cij=Cij+Ai
5、k*Bkj; printf(%4d,Cij); printf(n); 六结果展示 程序1和2的运行结果分别如图1-1和1-2所示: 图1-1 图1-2 七实验讨论与总结1.本实验考察了对数据文件的建立、读入和试用,是一个突破; 2.第一个矩阵相乘中出现小数,故应用float数据类型;第二个矩阵中全是整数,故用int型即可。 3.对于输出结果的排版需要格外注意,应灵活使用输出格式符使其美观完整。 4.文件操作的基本函数(打开、关闭、输入和输出) fopen(打开文件) 相关函数 open,fclose 表头文件 #include 定义函数 FILE * fopen(const char * pa
6、th,const char * mode); 函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。 fclose(关闭文件) 相关函数 close,fflush,fopen,setbuf 表头文件 #include 定义函数 int fclose(FILE * stream); 函数说明 fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。 返回值 若关文件动作成功则返回0,有错误发生时则返回EOF并把错误代码存到errno。错误代码 EBADF表示参数stream非已打开的文件。 fsc
7、anf(输入函数) 功能:从一个流中执行格式化输入 表头文件:#include 函数原型:int fscanf(FILE *stream, char *format,argument.); FILE* 一个FILE型的指针 char* 格式化输出函数,和scanf里的格式一样 返回值:成功时返回转换的字节数,失败时返回一个负数 fp = fopen(/local/test.c,a+);fscanf(fp,%s,str); fprintf 功能:传送格式化输出到一个文件中 表头文件:#include 函数原型:int fprintf(FILE *stream, char *format, arg
8、ument,.); FILE* 一个FILE型的指针 char* 格式化输入函数,和printf里的格式一样 返回值:成功时返回转换的字节数,失败时返回一个负数 fp = fopen(/local/test.c,a+); fprintf(fp,%sn,str)实验二 非线性方程求根1问题提出二要求 1.编制一个程序进行运算,最后打印出每种迭代格式的敛散情况; 2.用事后误差估计|xk+1-xk|1 | fabs(f11(2)1) printf(不满足收敛条件n); else k=0; i=f1(1);j=i; i=f1(j); while(fabs(i-j)eps) j=i; i=f1(j);
9、k+; printf(满足收敛条件,x%f,迭代次数为%d次n,i,k); if(fabs(f22(1)1 | fabs(f22(2)1) printf(不满足收敛条件n); else k=0; i=f2(1);j=i; i=f2(j); while(fabs(i-j)eps) j=i; i=f2(j);k+; printf(满足收敛条件,x%f,迭代次数为%d次n,i,k); if(fabs(f33(1)1 | fabs(f33(2)1) printf(不满足收敛条件n); else k=0; i=f3(1);j=i; i=f3(j); while(fabs(i-j)eps) j=i; i=
10、f3(j);k+; printf(满足收敛条件,x%f,迭代次数为%d次n,i,k); if(fabs(f44(1)1 | fabs(f44(2)1) printf(不满足收敛条件n); else k=0; i=f4(1);j=i; i=f4(j); while(fabs(i-j)eps) j=i; i=f4(j);k+; printf(满足收敛条件,x%f,迭代次数为%d次n,i,k); if(fabs(f55(1)1 | fabs(f55(2)1) printf(不满足收敛条件n); else k=0; i=f5(1);j=i; i=f5(j); while(fabs(i-j)eps) j
11、=i; i=f5(j);k+; printf(满足收敛条件,x%f,迭代次数为%d次n,i,k); if(fabs(f66(1)1 | fabs(f66(2)1) printf(不满足收敛条件n); else k=0; i=f6(1);j=i; i=f6(j); while(fabs(i-j)eps) j=i; i=f6(j);k+; printf(满足收敛条件,x%f,迭代次数为%d次n,i,k); 五结果展示程序运行结果如图2-3所示: 图2-3六实验讨论与总结1.完成本实验相当于实现了将迭代算法转化成程序语言这一突破;2.本实验考察众多容易忽视的细节和学生的仔细程度,比如六个函数转化成C
12、语言时,语法会出现众多不适,括号较多,很容易出错;另一方面,在用pow函数求x的y次方时,容易将x的1/3次方写成pow(x,1/3),这样写是错误的。因为1/3为两int型整数相除,系统执行结果为0,故应写成pow(x,1.0/3)。这是一个极容易忽视的地方; 3.方法改进由于求导法判定迭代收敛时,必定限制在一个区间内,而这个区间内只能存在一个根。因此用该方法判断出来的迭代结果如果是不收敛,并不能说明它对于其余的根也不收敛。因此,求导法只能求出f(x)的一个根,不能满足题目要求,而且求导需人工执行、过程繁琐。故对该算法进行改进:#includemath.h#includestdio.hdou
13、ble f1(double x) return (3*x+1)/(x*x); double f2(double x) return(pow(x,3)-1)/3);double f3(double x) return(pow(3*x+1,1.0/3); double f4(double x) return(1/(x*x-3); double f5(double x) return(pow(3+1/x),1.0/2); double f6(double x) return(x-(x*x*x-3*x-1)/(3*(x*x-1); /无需建立导函数void main() double i,j; dou
14、ble eps=1e-5; int k; k=0; i=f1(1);j=i; i=f1(j); while(fabs(i-j)eps ) j=i; i=f1(j);k+; if(ieps) j=i; i=f2(j);k+; if(ieps) j=i; i=f3(j);k+; if(ieps) j=i; i=f4(j);k+; if(ieps) j=i; i=f5(j);k+; if(ieps) j=i; i=f6(j);k+; if(i-99999) printf(不满足收敛条件n); else printf(满足收敛条件,x%f,迭代次数为%d次n,i,k);改进算法的程序运行结果如图2-4
15、所示: 图2-4 该方法的思想是:无区间限制迭代,如果迭代结束得到的结果为无穷大或无穷小,则说明该迭代不收敛。这种做法更加实用,而且可以看出,求得了两个根。但就科学性而言,教材上定理2.1的内容显示了迭代法收敛的条件。定义明确指出用求导判断收敛性,根据定义判断才是最科学的方法。但考虑到计算机语言的便利性就在于全过程无人工计算,而手动求导的方法与之相违背,从这个角度考虑,改进法更加具有说服力。但若只需求一个根而又要讲究科学性,我们仍然可以选择求导法。因此,我们应做到根据情况的不同来选择不同的适当方法来解决问题。 4.初始值的选取对迭代收敛有何影响?初始值的选取虽然不会改变迭代收敛的性质,但是会影
16、响其收敛速度。为了提高收敛速度,可设法提高初值的精度以减少迭代的次数。5.分析迭代收敛和发散的原因。迭代公式收敛与否,完全取决于迭代公式(x)的性态。这里考察到迭代法的几何意义:方程x=(x)的求根问题在几何上就是确定曲线y=(x)与直线y=x的交点P的横坐标。按教材图2.3演示的路径走下去,在曲线y=(x)上得到点列P0,P1,其横坐标分别按迭代公式所确定的迭代值x1,x2,如果迭代收敛,则点P1,P2,将越来越逼近所求的交点P。否则迭代法发散。这是迭代收敛和发散的本质原因。实验三 线性方程组的直接解法1问题提出 给出下列几个不同类型的线性方程组,请用适当算法计算其解。二要求 1.对上述三个
17、方程组分别利用Gauss顺序消去法与Gauss列主元消去法;平方根法与改进平方根法;追赶法求解(选择其一); 2.应用结构程序设计编出通用程序; 3.比较计算结果,分析数值解误差的原因; 4.尽可能利用相应模块输出系数矩阵的三角分解式。三实验目的和意义 1.通过该课题的实验,体会模块化结构程序设计方法的优点; 2.运用所学的计算方法,解决各类线性方程组的直接算法; 3.提高分析和解决问题的能力,做到学以致用; 4.通过三对角形线性方程组的解法,体会稀疏线性方程组解法的特点。四计算公式 本次实验的三个方程组,在此分别使用Gauss顺序消去法、平方根法和追赶法求解。下面给出这三种方法的计算公式。
18、1.Gauss顺序消去法计算公式 2.平方根法计算公式 3.追赶法计算公式五结构程序设计1.用Gauss顺序消去法求解线性方程组的程序设计如下(问题1):/Gauss顺序消去法-求解线性方程组/设计人:尹一君 20134651#includestdio.h#includemath.hvoid main() FILE *f; double a2020,b20,x20; double m,s; int i,j,k; if(f=fopen(Array3.txt,r)=NULL) return; for(i=1;i=10;i+) for(j=1;j=10;j+) fscanf(f,%lf,&aij);
19、 for(i=1;i=10;i+) fscanf(f,%lf,&bi); fclose(f); for(k=1;k10;k+) for(i=k+1;i=10;i+) for(j=k+1;j0;i-) s=0; for(j=i+1;j=10;j+) s=s+aij*xj; xi=(bi-s)/aii; for(i=1;i=10;i+) if(fabs(xi)0.5) xi=fabs(xi); printf(x%d=%fn,i,xi); 2.用平方根法求解对称正定阵系数阵线方程组的程序设计如下(问题2):/平方根法-求解对称正定阵系数阵线方程组/设计人:尹一君 20134651#includest
20、dio.h#includemath.hvoid main() FILE *f; double a1010,b10,l1010,x10,y10; double s1,s2,s3,s4; int i,j,k; if(f=fopen(Array4.txt,r)=NULL) return; for(i=1;i=8;i+) for(j=1;j=8;j+) fscanf(f,%lf,&aij); for(i=1;i=8;i+) fscanf(f,%lf,&bi); fclose(f); l11=pow(a11,1.0/2); for(i=1,j=2;j=8;j+) lji=aji/l11; for(i=2
21、;i=8;i+) for(j=i;j=8;j+) if(i=j) s1=0; for(k=1;k=i-1;k+) s1=s1+lik*lik; lii=pow(aii-s1),1.0/2); else s2=0; for(k=1;k=i-1;k+) s2=s2+ljk*lik; lji=(aji-s2)/lii; y1=b1/l11; for(i=2;i=8;i+) s3=0; for(k=1;k=1;i-) s4=0; for(k=i+1;k=8;k+) s4=s4+lki*xk; xi=(yi-s4)/lii; for(i=1;i=8;i+) if(fabs(xi)0.5) xi=fabs
22、(xi); printf(x%d=%fn,i,xi); 3.用追赶法求解三对角形线性方程组的程序设计如下(问题3):/追赶法-求解三对角形线性方程组/设计人:尹一君 20134651#includestdio.h#includemath.hvoid main() FILE *p; double a15,b15,c15,f15,l15,u15,x15,y15; int i; if(p=fopen(Array5.txt,r)=NULL) return; for(i=1;i=10;i+) fscanf(p,%lf,&ai); for(i=1;i=10;i+) fscanf(p,%lf,&bi); for(i=1;i=10;i+) fscanf(p,%lf,&ci); for(i=1;i=10;i+) fscanf(p,%lf,&fi); fclos
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1