中南林业科技大学《数值分析》实验指导书
一、本实验课程教学目的
《数值分析》实验课程是其理论课程的辅助手段,通过实验课程,让学生更好地理解相关理论和算法思想,并加强学生的实际动手能力。
二、实验项目
实验一Lagrange插值算法实现
1、实验目的
熟悉Lagrange插值算法,并能用计算机语言实现。
2、实验环境
TC3.0/VC++ 6.0编程环境。
3、相关理论
见教材
4、实验内容
1.用C/C++语言实现Lagrange插值算法。
5、实验步骤
1.认真熟悉教材关于Lagrange算法的理论分析;
2.以书中P.28 例2为实例进行数据测试。
[附:参考程序]
#include "stdio.h" // 输入输出scanf(), printf(),可改成输入输出流cin,cout
#include "conio.h" // 清除屏幕clrscr()
//定义并输入各个初始数据,根据各个题目不同修改
double x[]={0.32,0.34,0.36};
double y[]={0.314567,0.333487,0.352274};
double xx=0.3367;
double Lagrange(double xxx)
{
//采用算法计算出近似函数(多项式)
//此处采用Lagrange插值法,利用循环计算对称的基函数和最终结果
double result=0,temp;
for(int i=0;i<=2;i++)
{
temp=1;
for(int j=0;j<=2;j++)
{
if(j!=i)
{
temp=temp*(xxx-x[j])/(x[i]-x[j]);
}
}
result=result+temp*y[i];
}
return result;
}
void main()
{
printf("Sin(%f) = %f \n",xx,Lagrange(xx));
}
实验二Newton均差插值算法的实现
1、实验目的
熟悉Newton均差插值算法,并能用计算机语言实现。
2、实验环境
TC3.0/VC++ 6.0编程环境。
3、相关理论
见教材
4、实验内容
用C/C++语言实现Newton均差插值算法
5、实验步骤
1.认真熟悉教材关于Newton均差插值的理论分析;
2.以书中P.32 例4为实例进行数据测试。
[附:参考程序]
#include "stdio.h"
#include "conio.h"
#define N 10
double f[N][N];
double x[]={0.4,0.55,0.65,0.80,0.90,1.05};
double y[]={0.41075,0.57815,0.69675,0.88811,1.02652,1.25382};
double fx(int i,int j);
double S(int start,int end,double xx);
main()
{
int loopi,loopj,n;
double result,xx;
scanf("%d",&n);
scanf("%lf",&xx);
for(loopi=0;loopi<=n;loopi++)
{
f[loopi][0]=y[loopi];//零阶均差作为均差表二维数组的第0列}
for(loopi=1;loopi<=n;loopi++)
{
for(loopj=1;loopj<=loopi;loopj++)
{
f[loopi][loopj]=fx(loopi,loopj);
}
}
result=S(0,n,xx);
printf("Result is: %f",result);
getch();
return 1;
}
//求均差表
double fx(int i,int j)
{
if(j==0)
{
return f[i][j];
}
else
{
return (fx(i,j-1)-fx(i-1,j-1))/(x[i]-x[i-j]);//这种表示方法需要注意两个x的下标}
}
//用秦九韶算法计算差值多项式结果
double S(int start,int end,double xx)
{
if(start==end)
{
return f[end][end];
}
else
{
return (S(start+1,end,xx)*(xx-x[start])+f[start][start]);
}
}
实验三 NEWTON 差分插值算法实现
1、实验目的
熟悉NEWTON 差分插值算法,并能用计算机语言实现。
2、实验环境
TC3.0/VC++ 6.0编程环境。
3、相关理论
差分:k k k f f f -=?+1(向前差分)
1--=?k k k f f f (向后差分)
NEWTON 差分插值公式(此处为前插公式)
如果插值节点),2,1,0(0n k kh x x k =+=,要计算0x 附近点x 的函数值)(x f ,则可令10,0≤≤+=t th x x k ,于是相应的公式为: 002000!
)1()1(!2)1()(f n n t t t f t t f t f th x N n n ?+--++?-+?+=+
4、实验内容
1.用C/C++语言实现NEWTON 前插公式
5、实验步骤
1.认真熟悉教材关于NEWTON 差分插值算法的理论分析;
2.以书中P.34 例5为实例进行数据测试。
[附:参考程序]
#include "stdio.h"
#include "conio.h"
float f[10][10];
float fx(int i,int j);
float S(int n,float t,int end);
main()
{
int n=0,loopi,loopj;
float x,a,b,h,t;
float result;
clrscr();
printf("Please input a & b & h (a,b,h):");
scanf("%f,%f,%f",&a,&b,&h);
printf("\n");
printf("Please input ci shu :");
scanf("%d",&n);
printf("\n");
printf("Please input jie dian zhi(>=n+1 ge):\n");
for(loopj=0;loopj<=n;loopj++)
{
scanf("%f",&f[0][loopj]);
}
printf("\n");
printf("**********************************************************");
printf("\n");
printf("Please input the X:");
scanf("%f",&x);
printf("\n**********************************************************");
printf("\n");
t=(x-a)/h;
for(loopi=1;loopi<=n;loopi++)
{
for(loopj=0;loopj<=n-1;loopj++)
{
f[loopi][loopj]=fx(loopi,loopj);
}
}
printf("a=%f\n",a);
printf("b=%f\n",b);
printf("h=%f\n",h);
printf("t=%f\n",t);
printf("x=%f\n",x);
for(loopj=0;loopj<=n;loopj++)
{
for(loopi=0;loopi<=n-loopj;loopi++)
{
printf("%f ",f[loopi][loopj]);
}
printf("\n");
}
result=S(0,t,n);
printf("\n**********************************************************\n");
printf("Result is: %f",result);
getch();
return 1;
}
float fx(int i,int j)
{
if(i==0)
{
return f[i][j];
}
else
{
return (fx(i-1,j+1)-fx(i-1,j));
}
}
float S(int n,float t,int end)
{
if(n==end)
{
return f[n][0];
}
else
{
return S(n+1,t,end)*(t-n)/(n+1)+f[n][0];
}
}
实验四最小二乘法的法方程算法实现
1、实验目的
熟悉最小二乘法的原理和基本思想,理解法方程的构造过程,并能用计算机语言实现。
2、实验环境
TC3.0/VC++ 6.0编程环境。
3、相关理论
见教材
4、实验内容
用C/C++语言依据最小二乘法构造其中的法方程。
(以后学习方程组的数值解法后增加解法方程的模块)
5、实验步骤
1.认真熟悉教材关于最小二乘法的理论分析;理解法方程的构造过程;
2.以书中P.75 例9为实例构造法方程,并输出方程组(不用求解)
[附:参考程序]
#include
#define N 4
#define M 1
double a[N][N],d[N];
double x[]={19.0,25.0,31.0,38.0,44.0},y[]={19.0,32.3,49.0,73.3,97.8},w[]={1.0,1.0,1.0,1.0,1.0}; #include
double FI(int c,int t)
{
switch (c)
{ //分情况确定FI (k)的表达式
case 0:
return 1;
case 1:
return x[t]*x[t];
}
//....
return 1;
}
void cal()
{
for(int k=0;k<=M;k++)
{
//算K行系数
for(int j=0;j<=M;j++)
{
a[k][j]=0;
for(int t=0;t<=N;t++)
{
a[k][j]=a[k][j]+w[t]*FI(k,t)*FI(j,t);
}
}
d[k]=0;
//算第K个常数
for(j=0;j<=N;j++)
{
d[k]=d[k]+w[j]*FI(k,j)*y[j];
}
}
}
void main()
{
cout<<"The Matrix is:\n";
cal();
//输出方程组
for(int i=0;i<=M;i++)
{
for(int j=0;j<=M;j++)
{
cout< if(j else cout<<" = "; } cout< cout<<"\n"; } } 实验五Romberg求积算法的实现 1、实验目的 熟悉Romberg求积算法,并能用计算机语言实现。 2、实验环境 TC3.0/VC++ 6.0编程环境。 3、相关理论 数值求积的基本思想是通过积分中值定理将积分转化为函数的四则运算。利用梯形公 式、Simpson 公式、Cotes 公式、Romberg 公式间的关系,可构造出由梯形公式计算Romberg 公式的方法。 对于积分?=b a dx x f I )(,将积分区间[a,b]划分为n 等分,分点 n a b h n k kh x k -= ==),,2,1,0( ,则相应的复化梯形公式为: ∑-=+=1 )]()([2n k k k n x f x f h T , Simpson 公式与复化梯形公式关系: n n n T T S 3 1342-= Cotes 公式与Simpson 公式关系: n n n S S C 15 115162-= Romberg 公式与Cotes 公式关系: n n n C C R 63163642-= 4、实验内容 用C/C++语言实现Romberg 求积算法 5、实验步骤 1.认真熟悉教材关于求积算法的理论分析; 2.以书中P.108 例3为实例进行数据测试。 [附:参考程序] #include "stdio.h" #include "math.h" float T(int n,float a,float b); float S(int n,float a,float b); float C(int n,float a,float b); float R(int n,float a,float b); float f[100]; main() { int n; float a,b,result; printf("Please input n,a,b:"); scanf("%d,%f,%f",&n,&a,&b); printf("\n"); result=R(n,a,b); //求最后的Romberg 公式计算结果 } float T(int n,float a,float b) { float h,s=0; float x; h=(b-a)/n; for (int i=0;i<=n;i++) { x=a+i*h; if(x==0) { f[i]=1; } else { f[i]=sin(x)/x; //此处是计算函数f(x)在xi这点的函数值} if (i==0 || i==n) { s=s+f[i]; } else { s=s+2*f[i]; //除了首尾节点,其他节点计算2次 } } return (h/2*s); } float S(int n,float a,float b) { float temp=0; temp=4.0/3*T(2*n,a,b)-1.0/3*T(n,a,b); return temp; } float C(int n,float a, float b) { float temp=0; temp=16.0/15*S(2*n,a,b)-1.0/15*S(n,a,b); return temp; } float R(int n,float a, float b) { float temp=0; temp=64.0/63*C(2*n,a,b)-1.0/63*C(n,a,b); return temp; } 实验六高斯列主元素消去法算法实现 1、实验目的 熟悉消去法解方程组的原理和基本思想,并能用计算机语言实现。 2、实验环境 TC3.0/VC++ 6.0编程环境。 3、相关理论 高斯消去法解线性方程组是最常用的解线性方程组的方法。而高斯列主元素消去法只是为了避免选用绝对值小的元素作为主元的一种改进方法。 Ax 来说,可以通过将系数矩阵化为上三角形矩阵,从而采用回代对于线性方程组b 过程求解出线性方程组的解来。 4、实验内容 用C/C++语言实现高斯列主元素消去法算法 5、实验步骤 1.认真熟悉教材关于高斯消去法的理论分析;并理解其算法过程描述。 2.以书中P.148 例4为实例进行数据测试。 [附:参考程序] #include "math.h" // fabs() #include "stdlib.h" // exit() #include "stdio.h" // scanf(), printf() #include "conio.h" // clrscr() float a[10][10]; float b[10]; float det; float exchange(int i,int j,int n); void myexit(int i); main() { int n,loopi,loopj,k,maxi; float max,sum; clrscr(); printf("Please input jieshu n:"); scanf("%d",&n); printf("\nPlease input a[i][j]:"); for(loopi=1;loopi<=n;loopi++) { for(loopj=1;loopj<=n;loopj++) { scanf("%f",&a[loopi][loopj]); } } printf("\nPlease input b[i]:"); for(loopi=1;loopi<=n;loopi++) { scanf("%f",&b[loopi]); } printf("\n"); printf("**********************************************************"); printf("\n"); printf("your formuler is:\n"); for(loopi=1;loopi<=n;loopi++) { for(loopj=1;loopj<=n;loopj++) { if(loopj==n) { printf("%6.3f x%d = %6.3f\n",a[loopi][loopj],loopj,b[loopi]); } else { printf("%6.3f x%d + ",a[loopi][loopj],loopj); } } } printf("\n"); printf("**********************************************************"); printf("\n"); /*************************************************** now,let's begin to calculate the result! ***************************************************/ det=1.0; for(k=1;k<=n-1;k++) { maxi=k; max=a[k][k]; for(loopi=k+1;loopi<=n;loopi++) { if(fabs(a[loopi][k])>fabs(max)) { max=a[loopi][k]; maxi=loopi; } } if(max==0) { det=0; myexit(k); } if(maxi!=k) { exchange(maxi,k,n); } for(loopi=k+1;loopi<=n;loopi++) { a[loopi][k]=a[loopi][k]/a[k][k]; for(loopj=k+1;loopj<=n;loopj++) { a[loopi][loopj]=a[loopi][loopj]-a[loopi][k]*a[k][loopj]; } b[loopi]=b[loopi]-a[loopi][k]*b[k]; } det=a[k][k]*det; } if(a[n][n]==0) { det=0; myexit(n); } b[n]=b[n]/a[n][n]; for(loopi=n-1;loopi>=1;loopi--) { sum=0; for(loopj=loopi+1;loopj<=n;loopj++) { sum=sum+a[loopi][loopj]*b[loopj]; } b[loopi]=(b[loopi]-sum)/a[loopi][loopi]; } det=a[n][n]*det; printf("\n**********************************************************\n"); printf("Result is: \n"); for(loopj=1;loopj<=n;loopj++) { printf("x%d = %10.5f",loopj,b[loopj]); printf("\n"); } printf("det(A) = %10.5f",det); getch(); return 1; } float exchange(int i,int j,int n) { int loopk; float temp; for(loopk=1;loopk<=n;loopk++) { temp=a[i][loopk]; a[i][loopk]=a[j][loopk]; a[j][loopk]=temp; } temp=b[i]; b[i]=b[j]; b[j]=temp; det=-det; return 0; } void myexit(int i) { printf("\n The DET(A)=0,some a[%d][%d] is 0!",i,i); exit(0); } 实验七追赶法算法实现 1、实验目的 熟悉追赶法解对角占优的三对角线方程组的原理和基本思想,并能用计算机语言实现。 2、实验环境 TC3.0/VC++ 6.0编程环境。 3、相关理论 见教材 4、实验内容 用C/C++语言实现追赶法算法 5、实验步骤 1.认真熟悉教材关于追赶法的理论分析;并理解其算法过程描述。 2.以书中P.177 第9题为实例进行数据测试。 [附:参考程序] #include "stdio.h" // scanf(), printf() #define N 10 float a[N],b[N],c[N],f[N],Beta[N],x[N],y[N]; main() { int n,i,j; float temp; //输入数据 printf("Please input jieshu n:"); scanf("%d",&n); printf("\nPlease input a[i]:"); for(i=2;i<=n;i++) { scanf("%f",&a[i]); } printf("\nPlease input b[i]:"); for(i=1;i<=n;i++) { scanf("%f",&b[i]); } printf("\nPlease input c[i]:"); for(i=1;i<=n-1;i++) { scanf("%f",&c[i]); } printf("\nPlease input f[i]:"); for(i=1;i<=n;i++) { scanf("%f",&f[i]); } printf("\n"); printf("**********************************************************"); printf("\n"); //开始计算 //1、计算BETA(i) Beta[1]=c[1]/b[1]; for(i=2;i<=n-1;i++) { Beta[i]=c[i]/(b[i]-a[i]*Beta[i-1]); } //2、求解y[i] y[1]=f[1]/b[1]; for(i=2;i<=n;i++) { y[i]=(f[i]-a[i]*y[i-1])/(b[i]-a[i]*Beta[i-1]); } //3、求解x[i] x[n]=y[n]; for(i=n-1;i>=1;i--) { x[i]=y[i]-Beta[i]*x[i+1]; } printf("Result is: \n"); for(i=1;i<=n;i++) { printf("x%d = %6.3f",i,x[i]); printf("\n"); } return 1; } 实验八高斯-塞德尔迭代法算法实现 1、实验目的 熟悉迭代法解线性方程组的原理和基本思想,并能用计算机语言实现。 2、实验环境 TC3.0/VC++ 6.0编程环境。 3、相关理论 见教材 4、实验内容 用C/C++语言实现高斯-塞德尔迭代法算法 5、实验步骤 1.认真熟悉教材关于高斯-塞德尔迭代法的理论分析; 2.以书中P.189 例6为实例进行数据测试。 [附:参考程序] #include "iostream.h" #include "math.h" #define N 10 #define MaxN 1000 #define eps 0.00001 float a[N][N],b[N],xk[N],xk1[N]; void main() { int n,i,j,k; float temp,max; cout<<"Please input n:"; cin>>n; cout< cout<<"please input a[i][j]:"< for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { cin>>a[i][j]; } } cout<<"please input b[i]:"< for(i=1;i<=n;i++) { cin>>b[i]; } cout<<"********************************************************"< cout<<"your formuler is:\n"; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(j==n) { cout< } { cout< } } } cout< cout<<"********************************************************"< for(i=1;i<=n;i++) { xk[i]=xk1[i]=0.0; } for(k=1;k<=MaxN;k++) { for(i=1;i<=n;i++) { temp=0.0; for(j=1;j<=n;j++) { if(j { temp=temp+a[i][j]*xk1[j]; } else if(j>i) { temp=temp+a[i][j]*xk[j]; } } xk1[i]=(b[i]-temp)/a[i][i]; } max=fabs((double)(xk1[1]-xk[1])); for(i=1;i<=n;i++) { if(fabs((double)(xk1[i]-xk[i]))>max) { max=fabs((double)(xk1[i]-xk[i])); } } if(max { } else { for(i=1;i<=n;i++) { xk[i]=xk1[i]; } } } if(k { cout<<"Result is:"< for(i=1;i<=n;i++) { cout<<"X["< } cout<<"die dai ci shu k = "< } else { cout<<"Error!"; } } 实验九SOR迭代法算法实现 1、实验目的 熟悉迭代法解线性方程组的原理和基本思想,并能用计算机语言实现。 2、实验环境 TC3.0/VC++ 6.0编程环境。 3、相关理论 见教材 4、实验内容 用C/C++语言实现SOR迭代法算法 5、实验步骤 1.认真熟悉教材关于SOR迭代法的理论分析; 2.以书中P.195例9为实例进行数据测试。 [附:参考程序] #include "iostream.h" #include "math.h" #define N 10 #define MaxN 1000 #define eps 0.00001 #define w 1.4 //修改此处松弛因子,看迭代次数(0.6-17次,0.8-11次,0.9-9次,0.95-9次,1.0-7次,1.05-8次,1.1-9次,1.3-17次) float a[N][N],b[N],xk[N],xk1[N],xtemp; void main() { int n,i,j,k; float temp,max; cout<<"Please input n:"; cin>>n; cout< cout<<"please input a[i][j]:"< for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { cin>>a[i][j]; } } cout<<"please input b[i]:"< for(i=1;i<=n;i++) { cin>>b[i]; } cout<<"********************************************************"< cout<<"your formuler is:\n"; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(j==n) { cout< } else {