cout<<'\n';
}//输出改变后的数组
//输出解'''''''''''''''''''''''''''''''''''''''''''''''''''''''//
floatx[10];
for(i=n-1;i>=1;i--)
{
x[n]=a[n][n+1]/a[n][n];
floatsum3=0;
for(j=i+1;j<=n;j++)
sum3+=a[i][j]*x[j];
x[i]=(a[i][n+1]-sum3)/a[i][i];
}//回代过程
for(i=1;i<=n;i++)
{
cout<<'x'<
}//输出解向量
}
结果:
方程的解为:
x1=-0.28923,x2=0.34544,x3=-0.71281,
x4=-0.22061,x5=-0.43040,x6=0.15431,
x7=-0.057823,x8=0.20105,x9=0.29023。
分析:
我感觉是提高了查错误点的能力和编循环语句的能力,即利用很规整的迭代公式进行编程。
另外列主元三角分解法的阶梯步骤有了更深的了解!
36.逐次超松弛迭代法
(1)编制解n阶线性方程组Ax=b的SOR方法的通用程序(要求
);
(2)对于35题中所给的线性方程组,取松弛因子
,容许误差
,打印松弛因子、迭代次数、最佳松弛因子及解向量。
程序为:
#include
#include
#defineeps0.5e-5//迭代误差
voidmain(void)
{
inti,j,l;
floatw,t;
floatm[9];
floatsum;
floata[9][9]={{31,-13,0,0,0,-10,0,0,0},{-13,35,-9,0,-11,0,0,0,0},{0,-9,31,-10,0,0,0,0,0},{0,0,-10,79,-30,0,0,0,-9},{0,0,0,-30,57,-7,0,-5,0},{0,0,0,0,-7,47,-30,0,0},{0,0,0,0,0,-30,41,0,0},{0,0,0,0,-5,0,0,27,-2},
{0,0,0,-9,0,0,0,-2,29}};
floatb[9]={-15,27,-23,0,-20,12,-7,7,10};
floatmax(floatm[9]);
for(t=1;t<=99;t++)
{
l=0;
floatx0[9]={1,1,1,1,1,1,1,1,1};
floatx1[9]={1,1,1,1,1,1,1,1,1};
w=t/50;
do
{
for(i=0;i<9;i++)
{x0[i]=x1[i];}
for(i=0;i<9;i++)
{
sum=0;
for(j=0;j
{
sum=sum+a[i][j]*x1[j];
}
for(j=i+1;j<9;j++)
{sum=sum+a[i][j]*x0[j];}
x1[i]=(1-w)*x0[i]+w*(b[i]-sum)/a[i][i];}//解出九个解
for(i=0;i<9;i++)
{
m[i]=x1[i]-x0[i];}
l++;
}while(max(m)>=eps);
if(max(m)<=eps)
{cout<<"迭代次数="<for(i=0;i<9;i++)
cout<<"x1"<<"["<
cout<<"-------------------------------------"<<'\n';}
}
}
floatmax(floatm[9])//求出最大的迭代误差
{
floatk;
k=(fabs(m[0]));
for(inti=1;i<9;i++)
{
if(fabs(m[i])>k)
k=fabs(m[i]);
}
returnk;
}
结果为:
ω迭代次数ω迭代次数ω迭代次数ω迭代次数
0.021291
0.04700
0.06486
0.08373
0.10303
0.12255
0.14221
0.16194
0.18173
0.20156
0.22142
0.24130
0.26120
0.28111
0.30103
0.3296
0.3490
0.3685
0.3880
0.4075
0.4271
0.4468
0.4664
0.4861
0.5058
0.5255
0.5453
0.5651
0.5848
0.6046
0.6244
0.6442
0.6641
0.6839
0.7037
0.7236
0.7434
0.7633
0.7832
0.8030
0.8229
0.8428
0.8627
0.8826
0.9025
0.9224
0.9423
0.9622
0.9821
1.0020
1.0219
1.0418
1.0617
1.0816
1.1015
1.1215
1.1414
1.1612
1.1810
1.2011
1.2212
1.2412
1.2613
1.2813
1.3014
1.3215
1.3415
1.3616
1.3817
1.4018
1.4219
1.4419
1.4620
1.4821
1.5022
1.5224
1.5425
1.5627
1.5830
1.6031
1.6234
1.6436
1.6639
1.6844
1.7049
1.7255
1.7460
1.7671
1.7881
1.8097
1.82121
1.84157
1.86228
1.88398
1.901582
1.925427
1.942178
1.961374
1.981009
从1.92到2.00均出现不合理的迭代次数,迭代次数偏大。
不是合理的迭代值。
当初值为x=(1,1,1,1,1,1,1,1,1,)T时,从上表可以看出,最佳松弛因子为ω=1.18,迭代次数仅为10次,方程的解为:
x1=-0.289231,x2=0.345437,x3=-0.712811,
x4=-0.220608,x5=-0.430400,x6=0.154309,
x7=-0.057823,x8=0.201054,x9=0.290229。
数值分析上机题
姓名:
戴载星学号:
040139
习题4
38.(上机题)3次样条插值函数
(1)编制求第一型3次样条插值函数的通用程序;
(2)已知汽车曲线型值点的数据如下:
0
1
2
3
4
5
6
7
8
9
10
2.51
3.30
4.04
4.70
5.22
5.54
5.78
5.40
5.57
5.70
5.80
端点条件为
=0.8,
=0.2。
用所编制程序求车门的3次样条插值函数S(x),并打印出S(i+0.5)(i=0,1,…9)。
解:
通用程序:
#include
voidmain(void)
{
floatx[11];//存放数组x[j]
floaty[11];//存放数组y[j]
floath[11];//存放数组h[j]
floatu[11];//存放数组u[j]
floatv[11];//存放数组v[j]
floatd[11];//存放数组d[j]
floatM[11];//存放数组M[j]
floatb[11];//存放数组b[j]
floatt[11],l[11],yy[11],s[4],aa1,aa2,aa3,aa4;
floats1[10];
inti,j,n;
floatxx;//x为区间值
//将初值初始化
cout<<"请输入n的值:
\n";
cin>>n;
cout<<"输入数组x:
\n";
for(i=0;i<=n;i++)cin>>x[i];
cout<<"输入数组y:
\n";
for(i=0;i<=n;i++)cin>>y[i];
//输入端点值
floatdf[2];
cout<<"输入两个端点值:
\n";
for(i=0;i<2;i++)cin>>df[i];
//利用书本上的算法求出所需要的值
//求出h[j]的值
for(j=0;j<=n-1;j++)
{
h[j]=x[j+1]-x[j];
cout<<'h'<<'['<}
cout<//求出u[j]和v[j]的初值
v[0]=1;
u[n]=1;
for(j=1;j<=n-1;j++)
{
u[j]=h[j-1]/(h[j-1]+h[j]);
v[j]=h[j]/(h[j-1]+h[j]);
}
//求出d[j]的值
for(j=1;j{d[j]=6*((y[j+1]-y[j])/h[j]-(y[j]-y[j-1])/h[j-1])/(h[j]+h[j-1]);}
d[0]=6*((y[1]-y[0])/h[0]-df[0])/h[0];
d[n]=6*(df[1]-(y[n]-y[n-1])/h[n-1])/h[n-1];
for(j=1;j<=n;j++)
{
cout<<'u'<<'['<}
cout<for(j=0;j{
cout<<'v'<<'['<}
cout<for(j=0;j<=n;j++)
{
cout<<'d'<<'['<}
cout<//利用书本上的追赶法求解方程组
for(i=0;i<=n;i++)
{b[i]=2;}
cout<t[0]=b[0];
yy[0]=d[0];
//消元过程
for(i=1;i<=n;i++)
{
l[i]=u[i]/t[i-1];
t[i]=b[i]-l[i]*v[i-1];
yy[i]=d[i]-l[i]*yy[i-1];
}
//回代过程
M[n]=yy[n]/t[n];
for(i=n-1;i>=0;i--)
{
M[i]=(yy[i]-v[i]*M[i+1])/t[i];
}
//将M[j]的值输出
for(i=0;i<=n;i++)
{cout<<'M'<<'['<
//输出插值多项式的系数
for(j=0;j{
s[0]=y[j];
s[1]=(y[j+1]-y[j])/h[j]-(M[j]/3+M[j+1]/6)*h[j];
s[2]=M[j]/2;
s[3]=(M[j+1]-M[j])/(6*h[j]);
cout<<"当x的值在区间"<<'x'<<'['<\n";
for(intk=0;k<4;k++)
{
cout<<'s'<<'['<}
cout<}
}
(2)编制的程序求车门的3次样条插值函数S(x):
x属于区间[0,1]时;S(x)=2.51+0.8(x)-0.0014861(x)(x)-0.00851395(x)(x)(x)
x属于区间[1,2]时;S(x)=3.3+0.771486(x-1)-0.027028(x-1)(x-1)-0.00445799(x-1)(x-1)(x-1)
x属于区间[2,3]时;S(x)=4.04+0.704056(x-2)-0.0404019(x-2)(x-2)-0.0036543(x-2)(x-2)(x-2)
x属于区间[3,4]时;S(x)=4.7+0.612289(x-3)-0.0513648(x-3)(x-3)-0.0409245(x-3)(x