计算方法上机题.docx
《计算方法上机题.docx》由会员分享,可在线阅读,更多相关《计算方法上机题.docx(15页珍藏版)》请在冰豆网上搜索。
![计算方法上机题.docx](https://file1.bdocx.com/fileroot1/2022-12/30/b0ba17c5-0e49-4a49-b613-13eac9c51d53/b0ba17c5-0e49-4a49-b613-13eac9c51d531.gif)
计算方法上机题
第八题:
一,题目
从函数表
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)先选取两个结点
与
使
[
],然后在区间[
]上作线性插值,即得f(x)≈
。
(2)选取距点x最近的三个结点
,
,
进行二次插值,即取f(x)≈
。
(3)n=5,
三,计算结果
(1)
x
0.15
0.31
0.47
f(x)
0.394039
0.380067
0.356927
(2)
x
0.15
0.31
0.47
f(x)
0.394482
0.380225
0.361399
(3)
x
0.15
0.31
0.47
f(x)
0.394473
0.380219
0.357222
四,结果分析
编程基本按照课本套公式,方法从
(1)至(3),计算结果越来越精确。
五,源程序
(1)
#include
intmain(void)
{
inti,j;
doublea[6],b[6],x,y;
printf("Enterx:
");
for(i=0;i<6;i++)
scanf("%lf",&a[i]);
printf("Enterf(x):
");
for(i=0;i<6;i++)
scanf("%lf",&b[i]);
for(j=0;j<3;j++){
printf("Enterx:
");
scanf("%lf",&x);
for(i=0;x>a[i];i++);
y=b[i-1]*(x-a[i])/(a[i-1]-a[i])+b[i]*(x-a[i-1])/(a[i]-a[i-1]);
printf("x=%lf,",x);
printf("y=%lf\n",y);
}
return0;
}
(2)
#include
intmain(void)
{
inti,j;
doublea[6],b[6],x,y;
printf("Enterx:
");
for(i=0;i<6;i++)
scanf("%lf",&a[i]);
printf("Enterf(x):
");
for(i=0;i<6;i++)
scanf("%lf",&b[i]);
for(j=0;j<3;j++){
printf("Enterx:
");
scanf("%lf",&x);
for(i=0;x>a[i];i++);
if((a[i+1]-x)<(x-a[i-2]))
{
y=b[i-1]*(x-a[i])/(a[i-1]-a[i])*(x-a[i+1])/(a[i-1]-a[i+1]);
y=y+b[i]*(x-a[i-1])/(a[i]-a[i-1])*(x-a[i+1])/(a[i]-a[i+1]);
y=y+b[i+1]*(x-a[i-1])/(a[i+1]-a[i-1])*(x-a[i])/(a[i+1]-a[i]);
printf("x=%lf,",x);printf("y=%lf\n",y);
}
else{
y=b[i-2]*(x-a[i-1])/(a[i-2]-a[i-1])*(x-a[i])/(a[i-2]-a[i]);
y=y+b[i-1]*(x-a[i-2])/(a[i-1]-a[i-2])*(x-a[i])/(a[i-1]-a[i]);
y=y+b[i]*(x-a[i-2])/(a[i]-a[i-2])*(x-a[i-1])/(a[i]-a[i-1]);
printf("x=%lf,",x);printf("y=%lf\n",y);
}
}
return0;
}
(3)
#include
intmain(void)
{
inti,j,k;
doublea[6],b[6],x,y,p;
printf("Enterx:
");
for(i=0;i<6;i++)
scanf("%lf",&a[i]);
printf("Enterf(x):
");
for(i=0;i<6;i++)
scanf("%lf",&b[i]);
for(j=0;j<3;j++)
{
y=0;
printf("Enterx:
");
scanf("%lf",&x);
for(i=0;i<6;i++){
p=1;
for(k=0;k<6;k++){
if(k!
=i)
p=p*(x-a[k])/(a[i]-a[k]);}
y=y+p*b[i];
}
printf("x=%lf,",x);printf("y=%lf\n",y);
}
return0;
}
六,附图
(1)
(2)
(3)
第九题:
一,题目
已知直升机旋转机翼外形曲线轮廓线上的某些型值点及端点处的一阶导数值
y`(x0)=1.86548,y`(x18)=-0.046115,
试计算该曲线上横坐标为2,4,6,12,16,30,60,110,180,280,400,515处点的纵坐标(要求该曲线具有二阶光滑度)。
k
0
1
2
3
4
5
6
0.52
3.1
8.0
17.95
28.65
39.62
50.65
5.28794
9.4
13.84
20.2
24.9
28.44
31.1
k
13
14
15
16
17
18
364.4
416.3
468
494
507
520
20.9
14.8
7.8
3.7
1.5
0.2
k
7
8
9
10
11
12
78
104.6
156.6
208.6
260.7
312.5
35
36.5
36.6
34.6
31.0
26.34
二,基本方法
根据课本图4-9流程图及追赶法解方程。
三,计算结果
x
2
4
6
12
16
30
y
7.834331
10.476880
12.358485
16.579653
19.093173
25.386597
x
60
110
180
280
400
515
y
32.804369
36.647886
35.917141
29.368427
16.799141
0.524459
四,结果分析
利用追赶法求M[i],比高斯消去法步骤更简单,虽然结果有微小偏差,尤其在s[515]处与课本结果偏差较大。
但在精度要求不高的情况下,追赶法可以减少工作量,提高工作效率。
五,源程序
#include
intmain(void)
{
inti,j;
doublea[19],b[19],h[19],s[18],t[18],g[19],x,y,p,q,f[19],m[20],n[20];
printf("输入左端点一阶导:
");
scanf("%lf",&p);
printf("输入右端点一阶导:
");
scanf("%lf",&q);
printf("Enterx:
");
for(i=0;i<19;i++)
scanf("%lf",&a[i]);
printf("Enterf(x):
");
for(i=0;i<19;i++)
scanf("%lf",&b[i]);
for(i=0;i<19;i++)
h[i]=a[i]-a[i-1];
for(i=1;i<18;i++)
s[i]=h[i]/(h[i]+h[i+1]);
for(i=1;i<18;i++)
t[i]=1-s[i];
for(i=1;i<18;i++)
g[i]=6/(h[i]+h[i+1])*((b[i+1]-b[i])/h[i+1]-(b[i]-b[i-1])/h[i]);
g[0]=6/h[1]*((b[1]-b[0])/h[1]-p);g[18]=6/h[18]*(q-(b[18]-b[17])/h[18]);
f[1]=0.5;
for(i=2;i<19;i++)
f[i]=t[i-1]/(2-s[i-1]*f[i-1]);
n[1]=g[0]/2;
for(i=2;i<20;i++)
n[i]=(g[i-1]-s[i-1]*n[i-1])/(2-s[i-1]*f[i-1]);
m[19]=n[19];
for(i=18;i>0;i--)
m[i]=n[i]-f[i]*m[i+1];
printf("输出M:
\n");
for(i=1;i<20;i++)
printf("%lf",m[i]);
for(j=0;j<12;j++){
printf("\n");
printf("Enterx:
");
scanf("%lf",&x);
for(i=0;x>a[i];i++);
y=m[i]*(a[i]-x)*(a[i]-x)*(a[i]-x)/h[i]/6;
y=y+m[i+1]*(x-a[i-1])*(x-a[i-1])*(x-a[i-1])/h[i]/6;
y=y+(b[i-1]-m[i]*h[i]*h[i]/6)*(a[i]-x)/h[i];
y=y+(b[i]-m[i+1]*h[i]*h[i]/6)*(x-a[i-1])/h[i];
printf("f(x):
%lf",y);
}
return0;
}
六,附图
第十二题
一,题目
某类疾病发生率
‰和年龄段x(每五年为一段,例如0-5岁为第一段,6-10岁为第二段)之间有形如
的关系。
试根据观测得到的如下数据表,用最小二乘法确定式中的参数a和b,并计算相应的均方误差与最大偏差。
x
1
2
3
4
5
6
7
8
9
y
0.898
2.38
3.07
1.84
2.02
1.94
2.22
2.77
4.02
x
10
11
12
13
14
15
16
17
18
19
y
4.76
5.46
6.53
10.9
16.5
22.5
35.7
50.6
61.6
81.8
二,基本方法
(1)将非线性方程化为线性方程,对
等号两边取对数得到
。
(2)按照最小二乘法的原始定义,不对方程进行变换,而均方误差的方程式,通过求解非线性方程组来解决问题,此时要用到牛顿迭代法。
三,计算结果
(1)a=0.681361,b=0.230620,e=77.307455,m=18.328522
(2)第一次:
a=0.721560,b=0.249856,e=17.925350,m=8.1115274
第二次:
a=0.239368,b=0.310747,e=5.430872,m=3.467987.
四,结果分析
由以上结果对比,第二种方法结果更加精确,但是采用迭代法计算时,又必须多次选择初值才有可能取得较好的结果。
五,源程序
(1)
#include
#include
intmain(void)
{
inti;
doublea,b,e,m,a0,a1,b0,b1,y1,y2,x[19],y[19];
for(i=0;i<19;i++)
x[i]=i+1;
printf("x:
");
for(i=0;i<19;i++)
printf("%lf",x[i]);
printf("\ny:
");
for(i=0;i<19;i++)
scanf("%lf",&y[i]);
for(i=0;i<19;i++)
y[i]=log(y[i]);
a0=a1=b0=b1=y1=y2=0;
for(i=0;i<19;i++)
{
a1=a1+x[i];
y1=y1+y[i];
b0=b0+x[i];
b1=b1+pow(x[i],2);
y2=y2+x[i]*y[i];
}
a0=19;
b=(y2-y1*(b0/a0))/(b1-a1*(b0/a0));
a=(y1-b*a1)/a0;
a=exp(a);
for(i=0;i<19;i++)
y[i]=exp(y[i]);
e=m=0;
for(i=0;i<19;i++)
e=e+pow((a*exp((i+1)*b)-y[i]),2);
for(i=0;i<18;i++){
if(pow((a*exp((i+1)*b)-y[i]),2)>m)
m=pow((a*exp((i+1)*b)-y[i]),2);
else;
}
printf("a=%lfb=%lfe=%lfm=%lf\n",a,b,e/19,sqrt(m));
return0;
}
(2)
#include
#include
intmain(void)
{
inti,j;
doublea,b,e,m,f,f1,f2,g,g1,g2,c,d,x[19],y[19];
for(i=0;i<19;i++)
x[i]=i+1;
printf("x:
");
for(i=0;i<19;i++)
printf("%lf",x[i]);
printf("\ny:
");
for(i=0;i<19;i++){
scanf("%lf",&y[i]);
}
printf("Entera0:
");
scanf("%lf",&a);
printf("Enterb0:
");
scanf("%lf",&b);
f=f1=f2=g=g1=g2=0;
for(j=0;j<20;j++){
for(i=0;i<19;i++){
f=f+2*(a*exp((i+1)*b)-y[i])*exp((i+1)*b);
f1=f1+2*exp(2*(i+1)*b);
f2=f2+4*(i+1)*a*exp(2*(i+1)*b)-2*(i+1)*y[i]*exp((i+1)*b);
g=g+2*(a*exp((i+1)*b)-y[i])*(i+1)*a*exp((i+1)*b);
g1=g1+4*(i+1)*a*exp(2*(i+1)*b)-2*(i+1)*y[i]*exp((i+1)*b);
g2=g2+4*pow((i+1)*a,2)*exp(2*(i+1)*b)-2*pow((i+1),2)*a*y[i]*exp((i+1)*b);
}
c=f1*a+f2*b-f;
d=g1*a+g2*b-g;
b=(d-c*(g1/f1))/(g2-f2*(g1/f1));
a=(c-f2*b)/f1;
e=0;
m=0;
for(i=0;i<19;i++)
e=e+pow((a*exp((i+1)*b)-y[i]),2);
for(i=0;i<18;i++){
if(pow((a*exp((i+1)*b)-y[i]),2)>m)
m=pow((a*exp((i+1)*b)-y[i]),2);
}
printf("a=%lfb=%lf均方误差e=%lf最大偏差m=%lf\n",a,b,e/19,sqrt(m));
}
return0;
}
六,附图