数值分析大作业c语言版,数值分析大作业3

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

数值分析大作业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;

}

三、程序运行结果

你可能感兴趣的:(数值分析大作业c语言版)