数值计算
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
上机题目
1、利用Steffensen方法和Muller(抛物线)方法计算下列方程
在区间
上的实根,要求精度为
,并比较迭代次数。
Steffensen方法:
#include
#include
double f(double x)
{
double fx;
fx=log(6-pow(2,-x)-2*cos(x));
return(fx);
}
void main( )
{
double x,y,z,x1;
int n=0;
printf("please input x=");
scanf("%lf",&x1);
do
{
x=x1;
y=f(x);
z=f(y);
x1=x-pow((y-x),2)/(z-2*y+x);
n++;
}
while(fabs(x1-x)>1e-5);
printf("方程的根x1=%lf, 迭代次数n=%d\n",x1,n);
}
程序结果:当x=1.5时,方程的根x1=1.829384,迭代次数n=3
Muller(抛物线)方法:
#include
#include
double f(double x)
{
double fx;
fx=pow(2,-x)+exp(x)+2*cos(x)-6;
return fx;
}
void main()
{
int n=0,b1;
double t0,a,b,c,q0,w,x0,x1,x2,x3;
printf("please input three number x0,x1,x2:");
scanf("%lf%lf%lf",&x0,&x1,&x2);
do{
t0=(x2-x1)/(x1-x0);
q0=1+t0;
a=f(x0)*pow(t0,2)-f(x1)*t0*q0+f(x2)*t0;
b=f(x0)*pow(t0,2)-f(x1)*pow(q0,2)+f(x2)*(t0+q0);
c=f(x2)*q0;
if(b>=0)
b1=1;
else
b1=-1;
w=-2*c/(b+b1*sqrt(b*b-4*a*c));
x3=x2+w*(x2-x1);
n++;
x0=x1;
x1=x2;
x2=x3;
}while((fabs(w*(x2-x1))>1e-5));
printf("方程的根x=%lf,迭代次数n=%d\n",x3,n);
}
程序结果:输入x0,x1,x2的值:0.5,1.2,2.5
方程的根:x=1.829384,迭代次数:n=5
2、用Gauss列主元消去法求解下列方程组
#include
#include
void main()
{
int fp;
void Gac(int fp);
printf("输入'1'计算示例方程组的解,输入数字'i'(未知数的个数,i>1)计算输入方程组的解:\n");
scanf("%d",&fp);
Gac(fp);
}
void Gac(int n)
{ int i,j,k,ik;
int max(int k,int n,double A[20][21]);
void exchange(int ik,int k,int n,double A[20][21]);
void show(double A[20][21],double B[20][21],int n);
double A[20][21]={{4,0,6,0,2,12},{0,1,3,0,2,6},{6,3,19,2,6,36},{0,0,2,5,-5,2},{2,2,6,-5,16,21}},sum;
double B[20][21]={{4,0,6,0,2,12},{0,1,3,0,2,6},{6,3,19,2,6,36},{0,0,2,5,-5,2},{2,2,6,-5,16,21}};
if(n>1)
{ printf("请输入要求解方程组的增广矩阵:\n");
for(i=0;i<=n-1;i++)
for(j=0;j<=n;j++)
{
scanf("%lf",&A[i][j]);
B[i][j]=A[i][j];
}
}
if(n==1) n=5;
for(k=0;k<=n-2;k++)
{ ik=k;
ik=max(k,n,A);
if(A[k][k]==0) goto s1;
if(ik!=k) exchange(ik,k,n,A);
for(i=k+1;i<=n-1;i++)
{ A[i][k]=A[i][k]/A[k][k];
for(j=k+1;j<=n;j++)
A[i][j]=A[i][j]-A[i][k]*A[k][j];
}
}
if(A[n-1][n-1]==0) goto s1;
A[n-1][n]=A[n-1][n]/A[n-1][n-1];
for(i=n-2;i>=0;i--)
{ sum=0;
for(j=i+1;j<=n-1;j++)
{
sum=sum+A[i][j]*A[j][n];
}
A[i][n]=(A[i][n]-sum)/A[i][i];
}
show(A,B,n);
goto s2;
s1:printf("系数矩阵奇异,不求解\n");
s2:;
}
int max(int k,int n,double A[20][21])
{ double max;int ik,i;
max=0;
for(i=k+1;i<=n-1;i++)
{
if(fabs(A[i][k])>max)
{
max=fabs(A[i][k]);
ik=i;
}
}
return ik;
}
void exchange(int ik,int k,int n,double A[20][21])
{ double t;int i;
for(i=0;i<=n;i++)
{ t=A[k][i];
A[k][i]=A[ik][i];
A[ik][i]=t;
}
}
void show(double A[20][21],double B[20][21],int n)
{ int i,j;double sum;
printf("系数矩阵A= \n");
for(i=0;i<=n-1;i++)
{
for(j=0;j<=n;j++)
{
printf("%f ",B[i][j]);
}
printf("\n");
}
printf("b= \n");
for(i=0;i<=n-1;i++) printf("%f\n",B[i][n]);
printf("方程组的根为:\n");
for(i=0;i<=n-1;i++)
printf("x%d=%f\n",i+1,A[i][n]);
}
程序结果:x1=x2=x3=x4=x5=1.000000
3、已知函数表
x
0
0.1
0.2
0.3
0.4
f(x)
0.5
0.5389
0.5793
0.6179
0.7554
分别利用Lagrange和Newton插值法计算
的近似值。
Lagrange插值法;
#include
#include
void main()
{
double x[20],fx[20],xx,Lx,lix;
int i,j,k,n;
printf(" 请输入插值点的个数n:");
scanf("%d",&n);
printf(" 请输入插值节点值和插值点函数值:\n");
for(i=0;i<=n-1;i++)
{
printf("x%d f(%d)分别为:",i,i);
scanf("%lf%lf",&x[i],&fx[i]);
}
for(k=0;k<20;k++)
{
printf("x=");
scanf("%lf",&xx);
if(xx==9999)break;
Lx=0;
for(i=0;i<=n-1;i++)
{ lix=1;
for(j=0;j<=n-1;j++)
{
if(j!=i) lix=lix*(xx-x[j])/(x[i]-x[j]);
}
Lx=Lx+fx[i]*lix;
}
printf("L(%f)=%f\n",xx,Lx);
}
}
程序结果:L(0.130000)=0.553024
Newton插值法:
#include
#include
void main()
{
double x[20],fx[20],f[20][20],xx,Nx,t;
int i,j,k,n;
printf(" 请输入插值点的个数n:");
scanf("%d",&n);
printf(" 请输入插值节点值和插值点函数值:\n");
for(i=0;i<=n-1;i++)
{
printf("x%d f(%d)分别为:",i,i);
scanf("%lf%lf",&x[i],&fx[i]);
}
for(i=0;i<=n-1;i++) f[i][0]=fx[i];
for(j=1;j<=n-1;j++)
{
for(i=j;i<=n-1;i++)
{
f[i][j]=(f[i][j-1]-f[i-1][j-1])/(x[i]-x[i-j]);
}
}
for(k=0;k<20;k++)
{
printf("x=");
scanf("%lf",&xx);
if(xx==9999)break;
Nx=f[0][0];
for(i=1;i<=n-1;i++)
{ t=1.0;
for(j=0;j<=i-1;j++) t=t*(xx-x[j]);
Nx=Nx+t*f[i][i];
}
printf("N(%f)=%f\n",xx,Nx);
}
}
程序结果:L(0.130000)=0.553024
4、已知函数
及定义区间
,将定义区间分成 10等分。利用
方法编制三次样条插值函数
,满足第一类边界条件:
,并输出
的值。
(注:要求程序具有通用性)
#include
#include
void main()
{ int sp;
void M(int sp);
printf("输入'1'演示M方法样条差值,输入'2'利用M方法样条差值计算:\n");
for(;;)
{
scanf("%d",&sp);
if(sp!=1&&sp!=2)
printf("请重新输入‘1’或‘2’:\n");
else
break;
}
M(sp);
}
/********************************************************************************/
void M(int sp)
{ double x[20]={0},f[20]={0},h[20]={0},s1,s2;int n,i,k,y;
if(sp==1)
{
n=10;
printf("已知函数为:f(x)=5/(1+x*x)\n");
x[0]=-5;f[0]=5/(1+x[0]*x[0]);
for(i=1;i<=n;i++)
{ h[i]=1;
x[i]=x[i-1]+h[i];
f[i]=5/(1+x[i]*x[i]);
}
printf("满足第一类边界条件:\n");
k=1;
s1=0.0740;s2=-0.0740;
printf("s'(%d)=%f s'(%d)= %f\n",-5,s1,5,s2);
}
else
{
printf("输入区间分割份数n(n>0):\n");
printf("n=");
scanf("%d",&n);
printf("输入节点值和节点函数值\n");
w1: printf("x0、f(x0):");scanf("%lf %lf",&x[0],&f[0]);
for(i=1;i<=n;i++)
{
printf("x%d、f(x%d):",i,i);scanf("%lf %lf",&x[i],&f[i]);
h[i]=x[i]-x[i-1];
}
printf("x0=%f f(x0)=%f\n",x[0],f[0]);
for(i=1;i<=n;i++) printf("x%d=%f f(x%d)=%f\n",i,x[i],i,f[i]);
w2: printf("以上是您输入的节点信息,确认正确请输入‘9’,重新输入节点信息请输入‘0’:");
scanf("%d",&y);
if(y!=0&&y!=9)goto w2;
if(y==0) goto w1;
printf("请输入边界条件:\n");
printf("s'(%f)=",x[0]);
scanf("%lf",&s1);
printf("s'(%f)=",x[n]);
scanf("%lf",&s2);
printf("您输入的边界条件是:s'(%f)=%f s'(%f)=%f\n",x[0],s1,x[n],s2);
}
/********************************************************************************/
double D[20],A[20][21]={0};
for(i=1;i<=n-1;i++)
{ A[i][i]=2;
A[i][i+1]=h[i+1]/(h[i]+h[i+1]);
A[i][i-1]=h[i]/(h[i]+h[i+1]);
D[i]=6*((f[i+1]-f[i])/h[i+1]-(f[i]-f[i-1])/h[i])/(h[i]+h[i+1]);
}
A[0][0]=2;A[0][1]=1;D[0]=6*((f[1]-f[0])/h[1]-s1)/h[1];
A[n][n]=2;A[n][n-1]=1;D[n]=6*(s2-(f[n]-f[n-1])/h[n])/h[n];
/********************************************************************************/
double M[20]={0},L[20]={1},U[20]={1},V[20]={1},Y[20]={0};int t;void Gac(int t,double A[20][21]);
t=n;
for(i=0;i<=n-1;i++) V[i]=A[i][i+1];
U[0]=A[0][0];
for(i=1;i<=n;i++) {L[i]=A[i][i-1]/U[i-1];U[i]=A[i][i]-L[i]*V[i-1];}
Y[0]=D[0];
for(i=1;i<=t;i++) Y[i]=D[i]-L[i]*Y[i-1];
M[t]=Y[t]/U[t];
for(i=t-1;i>=0;i--) M[i]=(Y[i]-V[i]*M[i+1])/U[i];
/********************************************************************************/
double AA[20]={0},BB[20]={0},xx,Sx;
for(i=1;i<=n;i++)
{
AA[i]=(f[i]-f[i-1])/h[i]-h[i]*(M[i]-M[i-1])/6;
BB[i]=(f[i-1]/h[i]-h[i]*M[i-1]/6)*x[i]+(h[i]*M[i]/6-f[i]/h[i])*x[i-1];
}
printf("请输入要计算的节点值x=");scanf("%lf",&xx);
for(;;)
{ if(xxx[n]){printf("%f不在区间[%f,%f]内,请重新输入x=",xx,x[0],x[n]);scanf("%lf",&xx);}
else
{printf("%f在区间[%f,%f]内\n",xx,x[0],x[n]);break;}
}
printf("请输入节点所在的区间号(1到%d之间):\n",n);
w6:printf("i=");
scanf("%d",&i);
if(i<1||i>n) {printf("%d不在[%d,%d]内,重新输入i:\n",i,1,n);goto w6;}
if(xx>=x[i-1]&&xx<=x[i])
{printf("%f在第%d个区间[%f,%f]之间\n",xx,i,x[i-1],x[i]);
goto w7;
}
else
{
printf("%f不在第%d个区间[%f,%f]之间,请重新输入i:\n",xx,i,x[i-1],x[i]);
goto w6;
}
w7:Sx=(M[i-1]*pow(x[i]-xx,3)+M[i]*pow(xx-x[i-1],3))/(6*h[i])+AA[i]*xx+BB[i];
printf("S(%f)=%f\n",xx,Sx);
}
程序结果:s(2.5)=0.700244
_1206734168.unknown
_1316762270.unknown
_1316762894.unknown
_1316762299.unknown
_1301771112.unknown
_1316762248.unknown
_1301770920.unknown
_1204269785.unknown
_1204270009.unknown
_1204269662.unknown
_1181840767.unknown