该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
数值分析大作业3
一、设计方案
1.使用牛顿迭代法,对原题中给出的 ,,()的11*21组分别求出原题中方程组的一组解,于是得到一组和对应的。
2.对于已求出的,使用分片二次代数插值法对原题中关于的数表进行插值得到。于是产生了z=f(x,y)的11*21个数值解。
3.从k=1开始逐渐增大k的值,并使用最小二乘法曲面拟合法对z=f(x,y)进行拟合,得到每次的。当时结束计算,输出拟合结果。
4.计算的值并输出结果,以观察逼近的效果。其中。
具体实现方案如下:
1、求:
(1)Newton法解非线性方程组
,
其中,t, u, v ,w为待求的未知量,x, y为代入的已知量。
设,给定精度水平和最大迭代次数M,则解该线性方程组的迭代格式为:
迭代终止条件为,若时仍未达到迭代精度,则迭代计算失败。
其中,雅可比矩阵
,
,
(2)分片双二次插值:
根据题目给出的表格,
(其中,)
对于给定的,如果满足
则选择为插值节点,相应的插值多项式为
其中,
如果,则在式(2)中取i=1或i=4; 如果,则在式(2)中取u=1或u=4。
在区域上,将(i=0,1,…,10;0.5+0.2j,j=0,1,…20)代入到非线性方程组(1)中,用Newton法解出,再由分片双二次插值得,则有(i=0,1,…,10;j=0,1,…,20),即求出了。
2、求:
乘积型最小二乘拟合曲面:
(1)求系数矩阵C:
其中,
计算中涉及到对矩阵求逆,接着在后面将会具体说明列主元的高斯消去法求矩阵的逆的方法。
(2)确定最小的k值,拟合曲面:
设,给定精度水平和最大迭代次数N,则确定最小k值的迭代格式为:
迭代终止条件为,若时仍未达到迭代精度,则迭代计算失败。
待确定满足精度条件的最小k值后,就可以进行曲面拟合计算了。
3、关于列主元的高斯消去法求矩阵的逆:
设非奇异矩阵,且 ,则
,
对B和I列分块,有
即
其中,
应用列主元的高斯消去法线性解方程组 ,
则即为A的逆。
注:若A不可逆,则此算法失效。
二、程序代码
#include”stdafx.h”
#include
#include
#include
const int M= 500;
const doubleE=1.0e-12;
const double E1=1.0e-7;
const int kmax=9;
const double matrix[6][6]={
{-0.5, -0.34,0.14, 0.94, 2.06, 3.5},
{-0.42, -0.5,-0.26, 0.3, 1.18, 2.38},
{-0.18, -0.5,-0.5, -0.18, 0.46, 1.42},
{0.22, -0.34,-0.58, -0.5, -0.1, 0.62},
{0.78, -0.02,-0.5, -0.66, -0.5, -0.02},
{1.5, 0.46,-0.26, -0.66, -0.74, -0.5}
};
const double mat_t[6]={0, 0.2, 0.4, 0.6, 0.8, 1.0};
const double mat_u[6]={0, 0.4, 0.8, 1.2, 1.6, 2.0};
double U[11][21];
double C[kmax+1][kmax+1];
double max(double x,double y){
returnfabs(x)>fabs(y)?fabs(x):fabs(y);
}
void linear_solution(double f[4],double ff[4][4], double(&delta)[4])
{
int i, j, k,ik;
double tmp,mik;
for(k=0;k<3; k++)
{
ik=k;
for(i=k;i<4;i++)
if(fabs(ff[ik][k])
ik=i;
for(j=k;j<4;j++)
{
tmp=ff[k][j];
ff[k][j]=ff[ik][j];
ff[ik][j]=tmp;
}
tmp=f[k];
f[k]=f[ik];
f[ik]=tmp;
for(i=k+1;i<4;i++)
{
mik=ff[i][k]/ff[k][k];
for(j=k;j<4;j++)
ff[i][j]=ff[i][j]-mik*ff[k][j];
f[i]-=mik*f[k];
}
}
delta[3]=f[3]/ff[3][3];
for(k=2;k>=0;k--)
{
tmp=0;
for(j=k+1;j<4;j++)
tmp+=ff[k][j]*delta[j];
delta[k]=(f[k]-tmp)/ff[k][k];
}
}
void equation_solution(double x, double y,double&u,double &t){
doublev=1.0,w=1.0;
u=1.0;
t=1.0;
doubledelta[4],f[4],ff[4][4];
int k=0;
for(k=0;k<=M;k++)
{
f[0]=-1.0*(0.5*cos(t)+u+v+w-x-2.67);
f[1]=-1.0*(t+0.5*sin(u)+v+w-y-1.07);
f[2]=-1.0*(0.5*t+u+cos(v)+w-x-3.74);
f[3]=-1.0*(t+0.5*u+v+sin(w)-y-0.79);
ff[0][0]=-0.5*sin(t);
ff[0][1]=1.0;
ff[0][2]=1.0;
ff[0][3]=1.0;
ff[1][0]=1.0;
ff[1][1]=0.5*cos(u);
ff[1][2]=1.0;
ff[1][3]=1.0;
ff[2][0]=0.5;
ff[2][1]=1.0;
ff[2][2]=-sin(v);
ff[2][3]=1.0;
ff[3][0]=1.0;
ff[3][1]=0.5;
ff[3][2]=1.0;
ff[3][3]=cos(w);
linear_solution(f,ff,delta);
if(max(delta[3],max(delta[2],max(delta[0],delta[1])))/max(w,max(v,max(u,t)))<=E)
break;
else
{
t+=delta[0];
u+=delta[1];
v+=delta[2];
w+=delta[3];
if(k==M)
printf("非线性方程组迭代不成功!\n");
}
}
}
double interpolation(double a,double b){
inti,j,k,r,t1,t2;
double z=0.0;
i=int(fabs((a/0.2)+0.5));
j=int(fabs((b/0.4)+0.5));
if(i==0) i=1;
if(i==5) i=4;
if(j==0) j=1;
if(j==5) j=4;
for(k=i-1;k<=i+1;k++)
for(r=j-1;r<=j+1;r++)
{
doublesum=1.0;
sum*=matrix[k][r];
for(t1=i-1;t1<=i+1;t1++)
if(t1!=k)
sum*=(a-mat_t[t1])/(mat_t[k]-mat_t[t1]);
for(t2=j-1;t2<=j+1;t2++)
if(t2!=r)
sum*=(b-mat_u[t2])/(mat_u[r]-mat_u[t2]);
z+=sum;
}
return z;
}
void inverse(double (&matrix)[kmax+1][kmax+1],int k){
doublematrixT[kmax+1][kmax+1]={0.0};
double b[kmax+1][kmax+1]={0.0},tmp,mik;
int i,j,t,p,it;
for(i=0;i<=kmax;i++)
for(j=0;j<=kmax;j++)
if(i==j)
b[i][j]=1.0;
elseb[i][j]=0.0;
for(t=0;t
{
it=t;
for(i=t+1;i<=k;i++)
if(fabs(matrix[it][t])
it=i;
for(j=t;j<=k;j++)
{
tmp=matrix[it][j];
matrix[it][j]=matrix[t][j];
matrix[t][j]=tmp;
}
for(p=0;p<=k;p++)
{
tmp=b[t][p];
b[t][p]=b[it][p];
b[it][p]=tmp;
}
for(i=t+1;i<=k;i++)
{
mik=matrix[i][t]/matrix[t][t];
for(j=t+1;j<=k;j++)
matrix[i][j]-=mik*matrix[t][j];
for(p=0;p<=k;p++)
b[i][p]-=mik*b[t][p];
}
}
for(p=0;p<=k;p++)
{
matrixT[k][p]=b[k][p]/matrix[k][k];
for(i=k-1;i>=0;i--)
{
for(tmp=0.0,j=i+1;j<=k;j++)
tmp+=matrix[i][j]*matrixT[j][p];
matrixT[i][p]=(b[i][p]-tmp)/matrix[i][i];
}
}
for(i=0;i<=k;i++)
for(j=0;j<=k;j++)
matrix[i][j]=matrixT[i][j];
}
double surface_fitting(int k, double x, double y){
doubleB[11][kmax+1]={0.0},BT[kmax+1][11]={0.0};
doubleG[21][kmax+1]={0.0},GT[kmax+1][21]={0.0};
doubleBTB[kmax+1][kmax+1]={0.0},BTB1[kmax+1][kmax+1]={0.0},BTB2[kmax+1][kmax+1]={0.0},GTG[kmax+1][kmax+1]={0.0};
doublematrix1[kmax+1][11]={0.0},matrix3[21][kmax+1]={0.0};
double matrix2[kmax+1][21]={0.0};
double p,sum;
int i,j,t,r,s;
for(i=0;i<=10;i++)
for(j=0;j<=k;j++)
B[i][j]=pow(0.08*i,j);
for(i=0;i<=20;i++)
for(j=0;j<=k;j++)
G[i][j]=pow(0.5+0.05*i,j);
for(i=0;i<=10;i++)
for(j=0;j<=k;j++)
BT[j][i]=B[i][j];
for(i=0;i<=20;i++)
for(j=0;j<=k;j++)
GT[j][i]=G[i][j];
for(i=0;i<=k;i++)
for(j=0;j<=k;j++)
{
for(sum=0.0,t=0;t<=10;t++)
sum+=BT[i][t]*B[t][j];
BTB[i][j]=sum;
}
inverse(BTB,k);
for(i=0;i<=k;i++)
for(j=0;j<=k;j++)
{
for(sum=0.0,t=0;t<=20;t++)
sum+=GT[i][t]*G[t][j];
GTG[i][j]=sum;
}
inverse(GTG,k);
for(i=0;i<=k;i++)
for(j=0;j<=10;j++)
{
for(sum=0.0,t=0;t<=k;t++)
sum+=BTB[i][t]*BT[t][j];
matrix1[i][j]=sum;
}
for(i=0;i<=20;i++)
for(j=0;j<=k;j++)
{
for(sum=0.0,t=0;t<=k;t++)
sum+=G[i][t]*GTG[t][j];
matrix3[i][j]=sum;
}
for(i=0;i<=k;i++)
for(j=0;j<=20;j++)
{
for(sum=0.0,t=0;t<=10;t++)
sum+=matrix1[i][t]*U[t][j];
matrix2[i][j]=sum;
}
for(i=0;i<=k;i++)
for(j=0;j<=k;j++)
{
for(sum=0.0,t=0;t<=20;t++)
sum+=matrix2[i][t]*matrix3[t][j];
C[i][j]=sum;
}
p=0.0;
for(r=0;r<=k;r++)
for(s=0;s<=k;s++)
p+=C[r][s]*pow(x,r)*pow(y,s);
return p;
}
int _tmain(int argc, _TCHAR* argv[])
{
doublex,y,t,u,sum,sigma;
int i,j,k,kmin;
printf("数表:xi,yi,f(xi,yi)(i=0,1,2...10;j=0,1,2...,20):\n");
for(i=0;i<=10;i++)
for(j=0;j<=20;j++)
{
x=0.08*i;
y=0.5+0.05*j;
equation_solution(x,y,u,t);
U[i][j]=interpolation(t,u);
printf("x%d=%f,y%d=%f, f(x%d, y%d)=%.12le\n",i,x,j,y,i,j,U[i][j]);
}
printf("选择过程的k,σ值分别为:\n");
for(k=0;k<=kmax;k++)
{
sum=0.0;
for(i=0;i<=10;i++)
for(j=0;j<=20;j++)
sum+=pow(surface_fitting(k,0.08*i,0.5+0.05*j)-U[i][j],2);
printf("%d%.12le\n",k,sum);
if(sum<=E1)
{
kmin=k;
sigma=sum;
printf("达到精度要求的k,σ值分别为:\nk=%d,σ=%.12le\n",kmin,sigma);
printf("p(x,y)中的系数Crs(r=0,1,...,k;s=0,1,...,k):\n");
for(i=0;i<=k;i++)
for(j=0;j<=k;j++)
printf("Crs[%d][%d]=%.12le\n",i,j,C[i][j]);
break;
}
else if(k==kmax)
printf("无法达到曲面拟合精度要求!");
}
printf("数表:x*[i],y*[j],f(x*[i],y*[j]),p(x*[i],y*[j])(i=1,2,...,8;j=1,2,...,5):\n");
for(i=1;i<=8;i++)
for(j=1;j<=5;j++)
{
equation_solution(0.1*i,0.5+0.2*j,u,t);
printf("x*[%d]=%f,y*[%d]=%f\n",i,0.1*i,j,0.5+0.2*j);
printf("f(x*[%d],y*[%d])=%.12le,",i,j,interpolation(t,u));
printf("p(x*[%d],y*[%d])=%.12le\n",i,j,surface_fitting(kmin,0.1*i,0.5+0.2*j));
}
_getch();
return 0;
}
三、程序运行结果