当前位置:文档之家› 数值分析计算方法

数值分析计算方法

《计算方法》实验内容一.实验一:用两种不同的顺序计算644834.11000012≈∑=-n n ,分析其误差的变化。

1.实验目的:通过正序反序两种不同的顺序求和,比较不同算法的误差;了解在计算机中大数吃小数的现象,以后尽量避免;体会单精度和双精度数据的差别。

2.算法描述:累加和s=0;正序求和:对于n=1,2,3,......,10000s+=1.0/(n*n);反序求和:对于n=10000,9999,9998,.....,1s+=1.0/(n*n);3.源程序:#双精度型##include<stdio.h>cvoid main(){double s=0;int n;for(n=1;n<=10000;n++)s+=1.0/(n*n);printf("正序求和结果是:%lf\n",s);s=0;for(n=10000;n>=1;n--)s+=1.0/(n*n);printf("反序求和结果是:%lf\n",s);}#单精度型##include<stdio.h>void main(){float s=0;int n;for(n=1;n<=10000;n++)s+=1.0/(n*n);printf("正序求和结果是:%f\n",s);s=0;for(n=10000;n>=1;n--)s+=1.0/(n*n);printf("反序求和结果是:%f\n",s);}4.运行结果:双精度型运行结果:单精度型运行结果:5.对算法的理解与分析:舍入误差在计算机中会引起熟知的不稳定,算法不同,肯结果也会不同,因此选取稳定的算法很重要。

选取双精度型数据正反序求和时结果一致,但选用单精度型数据时,求和结果不一致,明显正序求和结果有误差,所以第一个算法较为稳定可靠。

二.实验二:1、拉格朗日插值按下列数据xi-3.0 -1.0 1.0 2.0 3.0yi1.0 1.52.0 2.0 1.0作二次插值,并求x1=-2,x2=0,x3=2.75时的函数近似值2牛顿插值按下列数据xi0.30 0.42 0.50 0.58 0.66 0.72yi1.04403 1.08462 1.11803 1.15603 1.19817 1.23223作五次插值,并求x1=0.46,x2=0.55,x3=0.60时的函数近似值.1.实验目的:通过拉格朗日插值和牛顿插值的实例,了解两种求解方法,并分析各自的优缺点。

2.算法描述:3.源程序:拉格朗日插值:#include<stdio.h>#define k 2void main(){double L,Y,a;double x[3];double y[3];for(int p=0;p<=2;p++)scanf("%lf%lf",&x[p],&y[p]);for(int q=0;q<=2;q++){Y=0;scanf("%lf",&a);for(int j=0;j<=k;j++){L=1;for(int i=0;i<=k;i++)if(i!=j)L*=(a-x[i])/(x[j]-x[i]);Y+=L*y[j];}printf("x=%lf的函数值是:%lf\n",a,Y);}}牛顿插值:#include<stdio.h>void main(){int i,j;double a[6][6],y,s,x;for(j=0;j<=1;j++)for(i=0;i<6;i++)scanf("%lf",&a[i][j]);for(j=2;j<=5;j++)for(i=j-1;i<=5;i++)a[i][j]=(a[i][j-1]-a[i-1][j-1])/(a[i][0]-a[i-j+1][0]);for(int k=0;k<3;k++){scanf("%lf",&x);y=0;for(i=0;i<5;i++){s=a[i][i+1];for(j=i-1;j>=0;j--)s*=x-a[j][0];y+=s;}printf("结果是:%lf\n",y);}4.运行结果:拉格朗日运行结果:牛顿插值运行结果:5.对算法的理解与分析:(1)拉格朗日插值:该公式是对一系列点加权求和。

内插通常优于外推。

选择的区间包括x,插值效果越好,高次插值通常优于低次插值,但并不是意味着插值次数越高越好。

优点:编程容易实现。

缺点:如果发现当前的插值方法不够精确,就要增加插值节点的个数。

拉格朗日基函数每一个都要重新计算,效率低。

(2)牛顿插值:优点:如果当前插值方法不稳定,需要增加插值节点个数,只需要计算新家节点所增加的差商即可,之前的计算结果可以被复用,比拉格朗日插值节省计算量,效率高,精度高,更为稳定。

三.实验三:分别用复化梯形公式和复化辛卜生公式计算f(x)=sin(x)/x的积分,并与准确值比较判断精度。

1.实验目的:通过实例体会各种算法的精度。

熟练掌握复化梯形,复化辛普森,复化柯特斯求积方法的程序。

2.算法描述:复化梯形:fc(x)=sinx/x,N等分,a,b是积分区间;令s=fc(a)+fc(b),对于i=a+1.0/N,a+2.0/N,.....(i<b)s+=2*fc(i);s*=double(b-a)/(2*N);输出s;复化辛普森:fc(x)=sinx/x,N等分,a,b是积分区间;令s=fc(a)+fc(b),对于i=a+1.0/N,a+2.0/N,.....(i<b)s+=2*fc(i);对于i=a+0.5/N,a+1.5/N,.....(i<b)s+=4*fc(i);s*=double(b-a)/(6*N);输出s;复化柯特斯:fc(x)=sinx/x,N等分,a,b是积分区间;令s=fc(a)+fc(b),对于i=a+1.0/(4*N),a+2.0/(4*N),.....(i<b)s+=32*fc(i);对于i=a+2.0/(4*N),a+6.0/(4*N),.....(i<b)s+=12*fc(i);对于i=a+1.0/N,a+2.0/N,.....(i<b)s+=14*fc(i);s*=double(b-a)/(90*N);输出s;3.源程序:#include<stdio.h>#include<math.h>#define N 8#define a 0#define b 1double fc(double x){double y;y=sin(x)/x;return y;}void tx()double s,i;s=fc(a)+fc(b);for(i=a+1.0/N;i<b;i+=1.0/N)s+=2*fc(i);s*=double(b-a)/(2*N);printf("复合梯形8等分求积结果是:%lf\n",s);}void xps(){double s,i;s=fc(a)+fc(b);for(i=a+1.0/N;i<b;i+=1.0/N)s+=2*fc(i);for(i=a+0.5/N;i<b;i+=1.0/N)s+=4*fc(i);s*=double(b-a)/(6*N);printf("复合辛普森8等分求积结果是:%lf\n",s); }void kts(){double s,i;s=fc(a)+fc(b);for(i=a+1.0/(4*N);i<b;i+=2.0/(4*N))s+=32*fc(i);for(i=a+2.0/(4*N);i<b;i+=1.0/N)s+=12*fc(i);for(i=a+1.0/N;i<b;i+=1.0/N)s+=14*fc(i);s*=double(b-a)/(90*N);printf("复合柯特思斯8等分求积结果是:%lf\n",s); }void main(){char d;scanf("%c",&d);if(d=='t')tx();if(d=='x')xps();if(d=='k')kts();}4.运行结果:5.对算法的理解与分析:他们都适用于求数值积分,而且都能提高计算的精度,他们都是在每个小区间上在使用梯形,辛普森,柯特斯求积公式,其中复化辛普森和复化柯特斯的收敛速度较快。

四.实验四:用改进欧拉方法解初值问题y’=x+y; y(0)=1。

0<x<1,取步长h=0.1计算,并与准确值y=-x-1-2e x相比较。

(p141习题第二题2)1.实验目的:熟悉常微分方程初值问题的求解方法;熟悉其算法;2.算法描述:3.源程序:4.运行结果:5.对算法的理解与分析:五.实验五:分别用下列方法求f(x)=x3-3x-1=0在x0=2附近的根。

根的准确值为x*=1.87938524…,要求准确到四位有效数字,并对比各种算法的计算量。

(1)二分法;(2)简单迭代法;(3)牛顿迭代法1.实验目的:通过对二分法,简单迭代法和牛顿迭代法的编程和上机实验,进一步体会他们在方程求根中的不同特点;比较三者的计算速度和计算精度。

2.算法描述:二分法:给定区间[a,b],e=pow(10,-4)*0.5(1)令c=(a+b)/2,保持b-a<e;(2)如果f(c)*f(a)=0,输出c;如果f(c)*f(a)<0,b=c,执行(1)否则a=c,执行(1)简单迭代法:3.源程序:二分法:#include<stdio.h>#include<math.h>double fc(double x){double y;y=x*x*x-3*x-1;return y;}void main(void){double fa=fc(1),fb=fc(3),a=1,b=3,f,x0;int k=0;for(;b>a&&b-a>=pow(10,-4)*0.5;){f=fc((a+b)/2);if(f==0){x0=(a+b)/2;break;}elseif(fa*f<0)b=(a+b)/2;elsea=(a+b)/2;k++;}x0=(a+b)/2;printf("近似根是:%lf 准确根是:1.87938524\n",x0);printf("迭代次数是:%d\n",k);}简单迭代法:#include<stdio.h>#include<math.h>double Iterate1(double x){double y;y=pow((3*x+1),1.0/3);return y;}double Derivative1(double x){double y;y=pow((3*x+1),-2.0/3);return y;}double Iterate2(double x){double y;y=(1-x*x*x)/3.0;return y;}double Derivative2(double x){double y;y=-x*x;return y;}double Iterate3(double x){double y;y=(3*x+1)/(x*x);return y;}double Derivative3(double x){double y;y=(-3*x-2)/(x*x*x);return y;}void main(void){double x2=2.0,x1;int k=0;double a1=Derivative1(x2);if(fabs(a1)<1){printf("迭代公式是x=pow((3*x+1),1.0/3);\n");do{x1=x2;x2=Iterate1(x1);k++;}while(fabs(x2-x1)>=pow(10,-4)*0.5);printf("近似根是:%lf 准确根是:1.87938524\n",x1);printf("迭代次数是:%d\n",k);}double a2=Derivative2(x2);if(fabs(a2)<1){printf("迭代公式是x=(1-x*x*x)/3.0;\n");do{x1=x2;x2=Iterate2(x1);k++;}while(fabs(x2-x1)>=pow(10,-4)*0.5);printf("近似根是:%lf 准确根是:1.87938524\n",x1);printf("迭代次数是:%d\n",k);}double a3=Derivative3(x2);if(fabs(a3)<1){printf("迭代公式是x=(3*x+1)/(x*x);\n");do{x1=x2;x2=Iterate3(x1);k++;}while(fabs(x2-x1)>=pow(10,-4)*0.5);printf("近似根是:%lf 准确根是:1.87938524\n",x1);printf("迭代次数是:%d\n",k);}}牛顿迭代法:#include<stdio.h>#include<math.h>double Iterate(double x){double y;y=x*x*x-3*x-1;return y;}double Derivative(double x){double y;y=3*x*x-3;return y;}void main(){double x0=2.0,x1;double f0,f01,f1,f11;f0=Iterate(x0);f01=Derivative(x0);int k=0;x1=x0-f0/f01;for(;fabs(x0-x1)>=pow(10,-4)*0.5;f0=f1,f01=f11){x0=x1;x1=x0-f0/f01;f1=Iterate(x1);f11=Derivative(x1);k++;if(f11==0){printf("牛顿迭代法失效\n");break;}}printf("近似根是:%lf 准确根是:1.87938524\n",x1);printf("迭代次数是:%d\n",k);}4.运行结果:二分法运行结果:简单迭代法运行结果:牛顿迭代法运行结果:。

相关主题