数值分析实验题.docx
《数值分析实验题.docx》由会员分享,可在线阅读,更多相关《数值分析实验题.docx(17页珍藏版)》请在冰豆网上搜索。
![数值分析实验题.docx](https://file1.bdocx.com/fileroot1/2023-5/28/bbfc1f7e-72da-402e-9eeb-85ba4969d035/bbfc1f7e-72da-402e-9eeb-85ba4969d0351.gif)
数值分析实验题
对所选试验题的具体说明:
1.插值问题数值实验题
1。
程序中的一些符号的解释:
*用牛顿插值法依据N个已知数据点及始函数值
*输入:
n--已知数据点的个数N-1
*x--已知数据点第一坐标的N维列向量
*y--已知数据点第二坐标的N维列向量
*xx-插值点第一坐标
*输出:
函数返回值所求插值点的第二坐标
2.该程序中的主要难点是用二维数组来定义差商。
for(i=1;i<=n;i++)
{
M[i][j]=(M[i][j-1]-M[i-1][j-1])/(M[i][0]-M[i-j+1][0]);
}
源程序:
#include
#include
voidmain()
{
charL;
do
{
doubleM[50][50];
doublex[50],y[50];
doubleX=1,xx=0,w=1,N=0,P,R=1;
intn;
cout<<"请输入所求均差阶数:
";
cin>>n;
for(inti=0;i<=n;i++)
{
cout<<"请输入x"<
"<cin>>x[i];
cout<<"请输入y"<
"<cin>>y[i];
M[i][0]=x[i];
M[i][1]=y[i];
}
for(intj=2;j<=n+1;j++)
{
for(i=1;i<=n;i++)
{
M[i][j]=(M[i][j-1]-M[i-1][j-1])/(M[i][0]-M[i-j+1][0]);
}
}
for(i=1;i<=n;i++)
{
cout<<"其"<
"<}
cout<<"请输入x的值:
x=";
cin>>xx;
for(i=0;i{
X*=xx-x[i];
N+=M[i+1][i+2]*X;
P=M[0][1]+N;
}
cout<<"其函数值:
y="<
for(i=0;i{
w*=xx-x[i];
R=fabs(M[n][n+1]*w);
}
cout<<"其绝对误差:
R="<cout<是请按'y'否则按'n'"<cin>>L;
}while(L=='y');
}
附:
运行结果
1.插值问题的运行结果:
注:
当x=1时原函数得值为:
0.038461538
请输入所求均差阶数:
2
请输入x0的值:
-1
请输入y0的值:
0.038461538
请输入x1的值:
0
请输入y1的值:
1
请输入x2的值:
1
请输入y2的值:
0.0344615
其1阶均差为:
0.961538
其2阶均差为:
-0.963538
请输入x的值:
x=1
其函数值:
y=0.0344615//比较精确。
还想算其它插值吗?
是请按'y'否则按'n'
y
请输入所求均差阶数:
4
请输入x0的值:
-1
请输入y0的值:
0.038461538
请输入x1的值:
-0.5
请输入y1的值:
0.137931034
请输入x2的值:
0
请输入y2的值:
1
请输入x3的值:
0.5
请输入y3的值:
0.137931034
请输入x4的值:
1
请输入y4的值:
0.038461538
其1阶均差为:
0.198939
其2阶均差为:
1.5252
其3阶均差为:
-3.31565
其4阶均差为:
3.31565
请输入x的值:
x=1
其函数值:
y=0.0384615//很精确!
还想算其它插值吗?
是请按'y'否则按'n'
请输入所求均差阶数:
8
请输入x0的值:
-1
请输入y0的值:
0.38461538
请输入x1的值:
-0.75
请输入y1的值:
0.066390041
请输入x2的值:
-0.5
请输入y2的值:
0.137931034
请输入x3的值:
-0.25
请输入y3的值:
0.390243902
请输入x4的值:
0
请输入y4的值:
1
请输入x5的值:
0.25
请输入y5的值:
0.390243902
请输入x6的值:
0.5
请输入y6的值:
0.137931043
请输入x7的值:
0.75
请输入y7的值:
0.06639041
请输入x8的值:
1
请输入y8的值:
0.038461538
其1阶均差为:
-1.2729
其2阶均差为:
3.11813
其3阶均差为:
-2.22927
其4阶均差为:
4.11377
其5阶均差为:
-18.2553
其6阶均差为:
40.0886
其7阶均差为:
-54.8146
其8阶均差为:
54.2519
请输入x的值:
x=1
其函数值:
y=0.0384615//很精确!
还想算其它插值吗?
是请按'y'否则按'n'
n
Pressanykeytocontinue
2.评价:
首先这个程序适用于任何给定的插值条件的多项式,并不局限于本题。
1.但是对于本题而言执行的效率并不高,原因在于每次都要计算x[i]和y[i]的值。
如:
输入n=3;
则出现以下的运行结果:
说明:
对于书上的实验题,{x[i]=-1+2/n;y[i]=1/(5+x[i]*x[i])}Ⅰ(其中n为阶数)
调试过程中出现的问题:
曾尝试把Ⅰ式写入程序但是出现了如下的问题:
其1阶均差为:
-1.#IND
其2阶均差为:
-1.#IND
其3阶均差为:
-1.#IND
请输入x的值:
x=1
其函数值:
y=-1.#IND
其绝对误差:
R=-1.#IND
还想算其它插值吗?
是请按'y'否则按'n'
2.对于上面程序中的M[i][j]的定义是该程序的关键,但是要用到牛顿插值中的阶商只要用一个,处于方便起见,选M[i][i]开始的时候我就是直接用的M[i][j+1];
输入所求均差阶数:
3
其1阶均差为:
-9.25596e+061
其2阶均差为:
-9.25596e+061
其3阶均差为:
-9.25596e+061
请输入x的值:
x=1
其函数值:
y=-1.#IND
其绝对误差:
R=-1.#IND
还想算其它插值吗?
是请按'y'否则按'n'
对于错误的分析:
关键我不明白#IND的含义。
3.在执行过程中必须输入一个确定的值不能输入一个表达式如:
“1/25”此数应该写成0.24,否则程序不能完整地执行下去会出现如下的形式:
如:
请输入所求均差阶数:
1
请输入x0的值:
-1
请输入y0的值:
1/26
请输入x1的值:
请输入y1的值:
其1阶均差为:
1
请输入x的值:
x=其函数值:
y=2
其绝对误差:
R=1
还想算其它插值吗?
是请按'y'否则按'n'
Pressanykeytocontinue
2.数值积分数值试验题(高斯三点法)
设计的思想:
先将高斯三点法中的三个点找出来分别为
0,-
.用gauss三点公式
=(b-a)/2*[0.8888889*f((a+b)/2)+0.5555556*f((a+b)/2-0.7745967*(b-a)/2)+0.5555556*f((a+b)/2+0.7745967*(b-a))]
然后用微分思想将区间[a,b]分成n等分,记下每个区间的起始点和终了点作为计算函数值的自变量的组成成员。
即原程序中的a1和a2.
最后将这些所计算的n个值进行累加,即可得到积分值。
源程序:
#include
#include
floatf1(floatx)
{return(x*x*x*x*x);}
floatf2(floatx)
{returnsin(x);}
floatgauss(float(*f)(floatx))//①
{
constt1=sqrt(0.6),t2=0,t3=-sqrt(0.6);
intn,t=0;
floata=0,b=1,a1,a2,h,y1,y2,y3,m=0,c,d,e;
cout<<"inputn=";
cin>>n;
h=(b-a)/n;
for(t=0;t{a1=a+t*h;
a2=a+(t+1)*h;
y1=(a1+a2)/2+(a1-a2)/2*t1;
y2=(a1+a2)/2+(a1-a2)/2*t2;
y3=(a1+a2)/2+(a1-a2)/2*t3;
c=f(y1);d=f(y2);e=f(y3);
m+=(h/18)*(5*c+8*d+5*e);}
returnm;//③
}
voidmain(void)
{charH;
do
{cout<<”第一个函数的积分为:
”<cout<<”第二个函数的积分为:
”<cout<是请按'y'否则按'n'"<cin>>H;}
while(H==’y’);}
附:
运行结果
2.数值积分问题的运行结果:
inputn=1
第一个函数的积分为:
0.03125//不精确。
inputn=1
第二个函数的积分为:
0.479426//比较精确。
还验算其它n的值吗?
是请按'y'否则按'n'
y
inputn=2
第一个函数的积分为:
0.119141//比较精确。
inputn=2
第二个函数的积分为:
0.464521//精确。
还验算其它n的值吗?
是请按'y'否则按'n'
y
inputn=10
第一个函数的积分为:
0.164591//很精确。
inputn=3
第二个函数的积分为:
0.461833//很精确!
还验算其它n的值吗?
是请按'y'否则按'n'
y
inputn=20
第一个函数的积分为:
0.166146//很精确!
inputn=4
第二个函数的积分为:
0.460897//很精确!
还验算其它n的值吗?
是请按'y'否则按'n'
n
Pressanykeytocontinue
说明:
课本上两个函数的积分实际值分别为0.16666666和0.460124569
调试过程中出现的问题:
Ⅰ.对于①处的函数指针的调用必须加上函数的类型float,否则编译不过去。
因为每个函数值都有一个float型的返回值,因此调用的时候必须加上函数类型。
for(inti=1;i<=n;i++)
{a1=a+t*h;
a2=a+(t+1)*h;
y1=(a1+a2)/2+(a1-a2)*t1;
y2=(a1+a2)/2+(a1-a2)*t2;
y3=(a1+a2)/2+(a1-a2)*t3;
c=f(y1);d=f(y2);e=f(y3);
m=(h/18)*(5*c+8*d+5*e);
sum+=m;
t++;
returnsum;
}
for(t=1;t<=n;t++)
{a1=a+t*h;
a2=a+(t+1)*h;
y1=(a1+a2)/2+(a1-a2)*t1;
y2=(a1+a2)/2+(a1-a2)*t2;
y3=(a1+a2)/2+(a1-a2)*t3;
c=f(y1);d=f(y2);e=f(y3);
m=(h/18)*(5*c+8*d+5*e);
sum+=m;
returnsum;
}
Ⅱ.如
果把该函数段下面的左图改写成右图则运行结果有误。
Ⅲ.对于②处的t必须从0到n-1开始不能从1到n开始,如果从1到n,则少了n份区间的第一段,而又多了后面的一个随机产生的一段,造成计算的错误。
Ⅳ.发现调试过程中随着n输入的值的增大,精度不断提高。
特别是当这两个函数的积分当n取1时误差特别大。
其实这也符合积分的思想,即把一个区间分成无穷等分。
故n越大则越精确。
Ⅴ.对于③returnm;应该写在for循环的语句的外面,不能写在其里面,因为这个返回值是在循环语句结束后最后一次行返回的。
Ⅵ.其实4里面说的也不是全对,因为我上面所选的函数的值是float型,其字长为四个字节也就是32位。
而其他人用的是double型其字长是八个字节也就是64位,其精度比较我的这个而言就高了许多,但这样的坏处就是占用机子的内存就相对而言大了。
Ⅶ.输入的n值不要太大,虽然这样结果比较精确,但这样机子不会立即出现结果,执行的时间就会比较长,因为这样计算的过程就相对的会增大不少。
#include
doublem(doublex,doublen)
{
returnx*x/24*(2+x*x*(-7+n*n*(14+n*(12+3*n))));//返回函数值
}
voidmain()
{
cout<<"线性方程组求解的数值实验题:
"<<'\n';
cout<<"根据实验结果解释发生的原因"<<'\n';
doublea[9][9]={0},b[9]={0},c[9][9]={0},d[9]={0},x[9]={0},y[9]={0};
doublesum=0;//定义初始值
intn,i,j,k;
for(n=2;n<10;n++)
{
cout<for(i=0;i{
for(j=0;j{
a[i][j]=1.0/(i+j+1);
}
b[i]=m((double)n+i,(double)n)-m((double)i,(double)n);
}
d[0]=a[0][0];
for(i=0;ic[i][0]=a[i][0]/d[0];
for(i=1;i{
for(k=0;k
sum+=c[i][k]*c[i][k]*d[k];
d[i]=a[i][i]-sum;
sum=0;
for(j=i;j{
for(k=0;ksum+=c[i][k]*d[k]*c[j][k];
c[i][j]=(a[i][j]-sum)/d[j];
sum=0;
}
}
y[0]=b[0];
for(i=1;i{
for(k=0;k
sum+=c[i][k]*y[k];
y[i]=b[i]-sum;
sum=0;
}
x[n-1]=y[n-1]/d[n-1];
for(i=n-2;i>=0;i--)
{
for(k=i+1;ksum+=c[k][i]*x[k];
x[i]=y[i]/d[i]-sum;
sum=0;
}
for(i=0;i{
cout<<'x'<
}
cout<<'\n';
}
}
#include
#include
doublef1(doublex)
{
return(x*x*x*x*x);//返回原函数f1的值
}
doublef2(doublex)
{
returnsin(x);//返回原函数f2的值
}
doublejf(double(*f)(double),doublea,doubleb,intn)
{
doubley=0,h;
inti;
h=(b-a)/n;//步长
for(i=1;i<=n;i++)
{
doublex=a+0.5*(2*i-1)*h;
y+=0.5*h*(0.8888889*f(x)+0.5555556*f(x-0.5*h*0.7745967)+0.5555556*f(x+0.5*h*0.7745967));//三点Gauss公式
}
returny;
}
voidmain(void)
{
cout<<"数值积分的实验题:
"<cout<<"请输入一个n的值:
"<intn;
cin>>n;
cout<<"f1的积分值:
"<cout<<"f2的积分值:
"<}