试验报告.docx
- 文档编号:23836637
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:29
- 大小:463.57KB
试验报告.docx
《试验报告.docx》由会员分享,可在线阅读,更多相关《试验报告.docx(29页珍藏版)》请在冰豆网上搜索。
试验报告
《计算方法》
实验报告册
姓名:
学号:
班级:
实验名称:
实验所属课程:
实验室(中心):
指导教师:
实验完成时间:
实验一数值稳定性实验……………………………………………………………..<3>
实验二非线性方程求根的数值解法………………………………………….<6>
实验三线性方程组的数值解法
(一)……………………………………..<11>
实验四线性方程组的数值解法
(二)……………………………………..<13>
实验五分段插值和拉格朗日插值实验……………………………………..<18>
实验六复合辛普森求积分实验…………………………………………………<21>
实验名称:
实验一数值稳定性实验
实验内容:
设
(1)从
尽可能精确的近似值出发,利用递推式
计算
的近似值。
(2)从
较粗糙的估计值出发,利用递推式
计算
的近似值。
(3)分析所得结果的可靠性以及出现这种现象的原因。
实验过程:
(1)先求的:
程序代码:
#include
main()
{
doubleI0=0.182322,In=0,It,n=1.0;
It=I0;
printf("n\t\tIt\n");
for(n=1;n<=20;)
{
In=-5*It+1.0/n;
It=In;
printf("%f\t%.15f\n",n,It);
n=n+1.0;
}
}
(2)以
(1)中用
算的的近似
最为
较粗糙的估计值。
程序代码:
#include
main()
{
doubleI20=42267422.243506,In=0,It,n=1.0;
It=I20;
printf("n\t\tIt\n");
for(n=20;n>0;)
{
In=-0.2*It+1.0/(5*n);
It=In;
printf("%f\t%.15f\n",n-1,It);
n=n-1.0;
}
}
实验结果分析:
第一小题程序运行结果如下:
但是当初始的
时运行结果为
显然,此时由于初始值的微小差异使得在经过20次的计算后结果已有了很大的差异。
对同一数学问题,为了求得其解,往往可以设计出多种不同的算法。
而不同的算法,在执行过程中引入的舍入误差以及舍入误差的累积情况,也往往是不同的。
假定初始值的误差为E,中间不断产生新误差,考察由E引起的误差累积是否增长。
在第二小题中,如果用
作为近似值计算
,计算得到的结果为0.182322,说明算法的稳定性不是问题,之所以出现上述问题,个人认为与小数点后保留的位数和初始值的小数点位数有关。
实验名称:
实验二非线性方程求根的数值解法
实验内容:
求方程
在区间
上的近似值,要求误差不超过
。
(1)利用二分法;
(2)取初值
,利用简单迭代法;
(3)取初值
,利用牛顿迭代法。
实验过程:
(1)二分法
程序代码:
#include"stdio.h"
#include"math.h"
floatfunction(floatx)
{
floaty;
y=pow(x,3)-x-1;
return(y);
}
main()
{
floata,b,E1=0.000001,E2=0.000001,x,y,y1,y2;
intk;
printf("请输入a和b......\n");
printf("a="),scanf("%f",&a);
printf("b="),scanf("%f",&b);
y1=function(a);
y2=function(b);
printf("k\t\tx\t\ty\n");
if(y1*y2>0)
{
printf("注意:
输入a和b的值无法计算出结果。
\n");
}
else
{
k=1;
do
{
x=(a+b)/2,y=function(x);
if(y>-E1&&y { printf("%f\t%f\t%f\t\n",k,x,y); break; } else { if(y1*y<0) { b=x; } else { a=x,y1=y; } } printf("%d\t%f\t%f\t\n",k,x,y); if(b-a>E2||b-a==E2) { k=k+1; } } while(b-a>E2||b-a==E2); } } (2)简单迭代法;迭代函数为 程序代码: #include"stdio.h" #include"math.h" main() { floatx0,x1,E=0.000001; intk=0,N=17; printf("请输入x0......\n"); printf("x0="),scanf("%f",&x0); printf("k\t\tx1\n"); do { k=k+1; x1=pow(x0+1,1.0/3); if(x1-x0>-E&&x1-x0 { printf("%d\t\t%f\n",k,x1); break; } else { x0=x1; } if(k==N) { printf("求算失败! \n"); } } while(k } (3)牛顿迭代法: 程序代码: #include"stdio.h" #include"math.h" main() { floatx0,x1,E=0.000001; intk=0,N=16; printf("请输入x0......\n"); printf("x0="),scanf("%f",&x0); printf("k\t\tx1\n"); do { k=k+1; x1=x0-(pow(x0,3)-x0-1)/(3*pow(x0,2)-1); if(x1-x0>-E&&x1-x0 { printf("%d\t\t%f\n",k,x1); break; } else { x0=x1; } if(k==N) { printf("求算失败! \n"); break; } } while(k } 实验结果分析: 程序一运行结果: 程序二运行结果如下: 程序三运行结果如下: 对三个程序的运行结果进行比较,发现牛顿迭代法有明显的优越性,在得到相同结果的前提下,用牛顿迭代法编的程序循环部分运行的次数最少。 当运行一个大型的程序时,程序运行所花的时间是必须考虑的。 时间太长,严重影响程序的整体性能,所以这时候要寻找一种尽量减少时间的算法。 实验名称: 实验三线性方程组的数值解法 (一) 实验内容: 求解线性方程组 并比较计算结果精度(方程组精确解为 ) (1)顺序消去法; (2)列主元消去法。 实验过程: (1)顺序消元法解该方程组的代码如下: #include"stdio.h" main() { floatA[4][5]={{1.1348,3.8326,1.1651,3.4017,9.5342},{0.5301,1.7875,2.5330,1.5435,6.3941}, {3.4129,4.9317,8.7643,1.3142,18.4231},{1.2371,4.9998,10.6721,0.0147,16.9237}}; floatT[4][5]; floatX[5]; inti,j,k; printf("按顺序消元法,将方程组转化为上三角矩阵形式如下: \n"); for(j=0;j<3;j++) { for(i=1;i<4;i++) { T[i][j]=A[i+j][j]/A[j][j]; for(k=j;k<5;k++) { A[i+j][k]=A[i+j][k]-A[j][k]*T[i][j]; } } } for(i=0;i<4;i++) { for(j=0;j<5;j++) { printf("%.4f\t",A[i][j]); } printf("\n"); } printf("方程组的解如下: \n"); X[4]=A[3][4]/A[3][3]; X[3]=(A[2][4]-A[2][3]*X[4])/A[2][2]; X[2]=(A[1][4]-A[1][3]*X[4]-A[1][2]*X[3])/A[1][1]; X[1]=(A[0][4]-A[0][3]*X[4]-A[0][2]*X[3]-A[0][1]*X[2])/A[0][0]; printf("x1=%.4f\t\nx2=%.4f\t\nx3=%.4f\t\nx4=%.4f\t",X[1],X[2],X[3],X[4]); } (2)列主元消去法解该方程的程序代码如下: #include"stdio.h" main() { floatA[4][5]={{1.1348,3.8326,1.1651,3.4017,9.5342},{0.5301,1.7875,2.5330,1.5435,6.3941}, {3.4129,4.9317,8.7643,1.3142,18.4231},{1.2371,4.9998,10.6721,0.0147,16.9237}}; floatT[4][5]; floatX[5],MAX[5],ZD[5]; inti,j,k,l,m; printf("按列组消元法,将方程组转化为上三角矩阵形式如下: \n"); for(j=0;j<3;j++) { MAX[j]=A[j][j]; for(l=1;l<4-j;l++) { if(A[l+j][j]>MAX[j]) { MAX[j]=A[l+j][j]; } } for(l=0;l<4-j;l++) { if(MAX[j]==A[l+j][j]) { for(m=j;m<5;m++) { ZD[m]=A[j][m]; A[j][m]=A[l+j][m]; A[l+j][m]=ZD[m]; } } } for(i=1;i<4;i++) { T[i][j]=A[i+j][j]/A[j][j]; for(k=j;k<5;k++) { A[i+j][k]=A[i+j][k]-A[j][k]*T[i][j]; } } } for(i=0;i<4;i++) { for(j=0;j<5;j++) { printf("%.4f\t",A[i][j]); } printf("\n"); } printf("方程组的解如下: \n"); X[4]=A[3][4]/A[3][3]; X[3]=(A[2][4]-A[2][3]*X[4])/A[2][2]; X[2]=(A[1][4]-A[1][3]*X[4]-A[1][2]*X[3])/A[1][1]; X[1]=(A[0][4]-A[0][3]*X[4]-A[0][2]*X[3]-A[0][1]*X[2])/A[0][0]; printf("x1=%.4f\t\nx2=%.4f\t\nx3=%.4f\t\nx4=%.4f\t",X[1],X[2],X[3],X[4]); } 实验结果分析: (1)顺序消元法程序运行结果如下所示: (2)列组消元法程序运行结果如下所示: 在此题中,用顺序消元法解方程的时候,当把矩阵化成上三角矩阵时,第三个方程的X3的系数与其他系数相比,显得格外的大。 第二个方程的X2的系数与其他系数相比,又显得格外的小。 而当用列组消元法,这种情况得到了很大程度的解决,对结果的准确性有了一定的提高。 在程序运行的时候弹出下图所示的对话框: 但是程序能正常运行处结果。 在改实验的程序代码中,大量的运用了FOR语句,很多运算都是通过循环来解决的。 使得程序的代码行数得到了大大的降低。 实验名称: 实验四线性方程组的数值解法 (二) 实验内容: 利用杜利特尔分解方法求解线性方程组 实验过程: 程序代码如下: #include"stdio.h" main() { floatA[6][6]={{1,2,4,7,11,16},{2,3,5,8,12,17},{4,5,6,9,13,18}, {7,8,9,10,14,19},{11,12,13,14,15,20},{16,17,18,19,20,21}},L[6][6]={{1,0,0,0,0,0},{0,1,0,0,0,0},{0,0,1,0,0,0}, {0,0,0,1,0,0},{0,0,0,0,1,0},{0,0,0,0,0,1}},U[6][6]={{1,2,4,7,11,16},{0,0,0,0,0,0},{0,0,0,0,0,0}, {0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0}}; floatB[6]={{10},{11},{12},{13},{14},{15}}; floatY[6],X[6]; inti,j; for(i=0;i<6;i++)L[i][0]=A[i][0]/L[0][0]; U[1][1]=(A[1][1]-L[1][0]*U[0][1])/L[1][1]; for(i=2;i<6;i++) { L[i][1]=(A[i][1]-L[i][0]*U[0][1])/U[1][1]; U[1][i]=(A[1][i]-L[1][0]*U[0][i])/L[1][1]; U[2][i]=(A[2][i]-L[2][0]*U[0][i]-L[2][1]*U[1][i])/L[2][2]; } for(i=3;i<6;i++) { L[i][2]=(A[i][2]-L[i][0]*U[0][2]-L[i][1]*U[1][2])/U[2][2]; U[3][i]=(A[3][i]-L[3][0]*U[0][i]-L[3][1]*U[1][i]-L[3][2]*U[2][i])/L[3][3]; } for(i=4;i<6;i++) { L[i][3]=(A[i][3]-L[i][0]*U[0][3]-L[i][1]*U[1][3]-L[i][2]*U[2][3])/U[3][3]; U[4][i]=(A[4][i]-L[4][0]*U[0][i]-L[4][1]*U[1][i]-L[4][2]*U[2][i]-L[4][3]*U[3][i])/L[4][4]; } L[5][4]=(A[5][4]-L[5][0]*U[0][4]-L[5][1]*U[1][4]-L[5][2]*U[2][4]-L[5][3]*U[3][4])/U[4][4]; U[5][5]=(A[5][5]-L[5][0]*U[0][5]-L[5][1]*U[1][5]-L[5][2]*U[2][5]-L[5][3]*U[3][5]-L[5][4]*U[4][5])/L[5][5]; printf("矩阵A: \n"); for(i=0;i<6;i++) { for(j=0;j<6;j++) { printf("%.0f\t",A[i][j]); } printf("\n"); } printf("矩阵L: \n"); for(i=0;i<6;i++) { for(j=0;j<6;j++) { printf("%.0f\t",L[i][j]); } printf("\n"); } printf("矩阵U: \n"); for(i=0;i<6;i++) { for(j=0;j<6;j++) { printf("%.0f\t",U[i][j]); } printf("\n"); } Y[0]=B[0]; Y[1]=B[1]-L[1][0]*Y[0]; Y[2]=B[2]-L[2][0]*Y[0]-L[2][1]*Y[1]; Y[3]=B[3]-L[3][0]*Y[0]-L[3][1]*Y[1]-L[3][2]*Y[2]; Y[4]=B[4]-L[4][0]*Y[0]-L[4][1]*Y[1]-L[4][2]*Y[2]-L[4][3]*Y[3]; Y[5]=B[5]-L[5][0]*Y[0]-L[5][1]*Y[1]-L[5][2]*Y[2]-L[5][3]*Y[3]-L[5][4]*Y[4]; printf("Y的值: \n"); printf("Y1=%.4f\nY2=%.4f\nY3=%.4f\nY4=%.4f\nY5=%.4f\nY6=%.4f\n",Y[0],Y[1],Y[2],Y[3],Y[4],Y[5]); X[5]=Y[5]/U[5][5]; X[4]=(Y[4]-U[4][5]*X[5])/U[4][4]; X[3]=(Y[3]-U[3][5]*X[5]-U[3][4]*X[4])/U[3][3]; X[2]=(Y[2]-U[2][5]*X[5]-U[2][4]*X[4]-U[2][3]*X[3])/U[2][2]; X[1]=(Y[1]-U[1][5]*X[5]-U[1][4]*X[4]-U[1][3]*X[3]-U[1][2]*X[2])/U[1][1]; X[0]=(Y[0]-U[0][5]*X[5]-U[0][4]*X[4]-U[0][3]*X[3]-U[0][2]*X[2]-U[0][1]*X[1])/U[0][0]; printf("方程的解X的值: \n"); printf("X1=%.4f\nX2=%.4f\nX3=%.4f\nX4=%.4f\nX5=%.4f\nX6=%.4f\n",X[0],X[1],X[2],X[3],X[4],X[5]); } 实验结果分析: 程序运行结果如下: 实验名称: 实验五分段插值和拉格朗日插值实验 实验内容: 从函数表 x 0.0 0.1 0.195 0.3 0.401 0.5 f(x) 0.39894 0.39695 0.39142 0.38138 0.36812 0.35206 出发,用下列方法计算f(0.15),f(0.31),f(0.47)的近似值; (1)分段线性插值 (2)分段二次插值 (3)全区间上拉格朗日插值 实验过程: (1)分段线性插值的代码如下: #include"stdio.h" main() { floatX[6]={0.0,0.1,0.195,0.3,0.401,0.5},Y[6]={0.39894,0.39695,0.39142,0.38138,0.36812,0.35206}; inti,n,t,YorN; floatx,y; do{ printf("请输入x的值: \nx="); scanf("%f",&x); for(i=0;i<6;i++) { if(x { t=i; break; } } y=Y[i-1]*(x-X[i])/(X[i-1]-X[i])+Y[i]*(x-X[i-1])/(X[i]-X[i-1]); printf("近似值Y为: %f\n",y); printf("是否继续进行插值计算? \n请输入1or0(1代表继续,0代表不继续)。 \n"); scanf("%d",&YorN); } while(YorN==1); } (2)分段二次插值的代码如下: #include"stdio.h" main() { floatX[6]={0.0,0.1,0.195,0.3,0.401,0.5},Y[6]={0.39894,0.39695,0.39142,0.38138,0.36812,0.35206}; inti,n,t,YorN; floatx,y; floatXCHZ[5]; do{ printf("请输入x的值: \nx="); scanf("%f",&x); for(i=0;i<6;i++) { if(x { t=i; break; } } y=Y[i-2]*(x-X[i-1])*(x-X[i])/((X[i-2]-X[i-1])*(X[i-2]-X[i]))+ Y[i-1]*(x-X[i-2])*(x-X[i])/((X[i-1]-X[i-2])*(X[i-1]-X[i]))+ Y[i]*(x-X[i-2])*(x-X[i-1])/((X[i]-X[i-2])*(X[i]-X[i-1])); printf("近似值Y为: %f\n",y); printf("是否继续进行插值计算? \n请输入1or0(1代表继续,0代表不继续)。 \n"); scanf("%d",&YorN); } while(YorN==1); } (3)全区间上拉格朗日插值程序代码如下: #include"stdio.h" main() { floatX[6]={0.0,0.1,0.195,0.3,0.401,0.5},Y[6]={0.39894,0.39695,0.39142,0.38138,0.36812,0.35206}; inti,n,t,YorN; floatx,y; floatXCHZ[5],F0,F1[5],F2[4],F3[3],F4[2],F5[1]; F0=Y[0]; for(i=0;i<5;i++) { F1[i]=(Y[i+1]-Y[i])/(X[i+1]-X[i]); } for(i=0;i<4;i++) { F2[i]=(F1[i+1]-F1[i])/(X[i+2]-X[i]); } for(i=0;i<3;i++) { F3[i]=(F2[i+1]-F2[i])/(X[i+3]-X[i]); } for(i=0;i<2;i++) { F4[i]
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 试验报告