计算方法 实验报告 拉格朗日 龙贝格龙格库塔.docx
《计算方法 实验报告 拉格朗日 龙贝格龙格库塔.docx》由会员分享,可在线阅读,更多相关《计算方法 实验报告 拉格朗日 龙贝格龙格库塔.docx(15页珍藏版)》请在冰豆网上搜索。
计算方法实验报告拉格朗日龙贝格龙格库塔
计算方法实验报告
班级:
华科大计算机xxx姓名:
刘荡学号:
U2009xxxx
◆实验内容
实验一(拉格朗日插值)
§公式
§算法描述
§流程图
§运行结果
§结果分析:
从运行结果可以看到,在一定范围内,当n增大时,在x=+5或-5附近,插值函数
在插值区间[-5,+5]的两端发生剧烈的震荡。
即随着插值节点的增多,被插值函数虽然在越来越多的点上取相同的函数值,但在插值节点之间,两者却相差甚远。
也即发生了Runge现象。
这也告诉我们,仅仅通过增加差值节点的个数,无法使插值多项式越来越逼近被插值函数。
实验二(龙贝格公式)
§公式
§算法描述
§流程图
§运行结果
§结果分析:
Romberg积分法是在积分步长逐步折半的过程中,用低精度求积公式的组合得到更高精度求积公式的一种方法,它算法简单,且收敛加速效果极其显著。
实验三(四阶龙格库塔)
§公式
k1=h*f(xn,yn);
k2=h*f(xn+h/2,yn+k1/2);
k3=h*f(xn+h/2,yn+k2/2);
k4=h*f(xn+h,yn+k3);
yn+1=yn+(k1+2*k2+2*k3+k4)/6;
§算法描述
§流程图
§运行结果
§结果分析:
龙格库塔方法在求解范围较大而精确度要求较高时是比较好的方法,它和欧拉法一样,可以直接从头算起,而且达到同样的精度,它所用的步长比欧拉法所用的步长大得多。
并且,随着步长的减小,四阶龙格库塔公式计算的结果精确度越来越高。
但是,龙格库塔公式计算量大。
◆实验体会:
经过本次实验,不仅让我对拉格朗日插值、龙贝格公式、龙格库塔公式的一些特性有了更多的了解,同时使我对C语言的编程更加熟练。
让我认识到,计算方法是一门理论与实践相结合的学科,从中我们不仅学到了很多有用的算法,而且也让我进一步了解了计算机是怎样实现数据之间的“计算”的。
另外,我也发现了自己的一些不足之处,比如说粗心、考虑不全面,调试程序没有耐心等。
总之,通过这次实验,让我收获了一份将理论付诸实践的乐趣,领略到了不同的计算方法的魅力,今后我会继续努力,用代码展现自己的精彩人生!
◆源程序即可执行文件:
见附录文件夹(源程序)。
◆开发及运行环境:
以上程序均在win-tc上通过,且在windows系统中运行无误。
本程序为多个C文件的运行,编者已将lagrange.c,romberg.c和runge.c三个子文件包含(#include)在了main.c中,所以,要查看运行结果,老师只需直接运行即可。
源代码,运行说明:
本程序为多个C文件的运行,编者已将lagrange.c,romberg.c和runge.c三个子文件包含(#include)在了main.c中,所以,要查看运行结果,老师只需直接用win-tc打开main.c,运行即可。
感谢使用!
主界面:
/*lagrange.c*/
floatreal_value(floatx)/*由被插值函数计算真实值*/
{
floaty;
y=1.0/(1+x*x);
returny;
}
floatcacul_value(floatx,intn)/*由构造的插值函数计算*/
{
inti,j;
floaty=0,xi,xj,yi,L;
for(i=0;i<=n;i++)
{
L=1.0;
xi=-5+(10*i*1.0)/n;
yi=real_value(xi);
for(j=0;j<=n;j++)
{
xj=-5+(10*j*1.0)/n;
if(j!
=i)L=L*(x-xj)/(xi-xj);
}
y+=yi*L;
}
returny;
}
voidlagrange()
{
intn,k;
charc;
floatx,xi,yi;
while
(1){
printf("\nInputdivisionn:
");/*输入等分数n*/
scanf("%d",&n);getchar();
printf("inputpointx(-5~5):
");/*输入待计算的插值点x*/
scanf("%f",&x);getchar();
printf("\nWhenx=%.3f,n=%d\n",x,n);
printf("real_value=%f\n",real_value(x));
printf("caculate_value=%f\n",cacul_value(x,n));
printf("error=%f",fabs(real_value(x)-cacul_value(x,n)));
printf("\n\ncontinue?
('Y'or'N'):
");
c=getchar();
if(c=='N'||c=='n')break;
}
}
/*romberg.c*/
doublefunction(doublex)/*被积函数*/
{
return4.0/(1+(x)*(x));
}
doublet(doublea,doubleb,intm)/*计算T1*/
{
inti,s=1;
doubleh=b-a,temp=0;
for(i=1;i<=m;i++)
{
s=s*2;
h=h/2.0;
}
if(s==1)return(function(a)+function(b))/2.0;
else{
for(i=1;i<=s/2;i++)
temp+=function((2*i-1)*h);
returnh*temp;
}
}
voidromberg()
{
intk;
doublea=0,b=1,T1,T2,S1,S2,C1,C2,R1,R2;
printf("\nlowerbounda=");
scanf("%lf",&a);
printf("upperboundb=");
scanf("%lf",&b);/*输入double型,必须用%lf*/
T1=t(a,b,0);
T2=T1/2.0+t(a,b,1);
S1=(4*T2-T1)/3.0;
T1=T2;
T2=T1/2.0+t(a,b,2);
S2=(4*T2-T1)/3.0;
C1=(16*S2-S1)/15.0;
T1=T2;
T2=T1/2.0+t(a,b,3);
S1=S2;
S2=(4*T2-T1)/3.0;
C2=(16*S2-S1)/15.0;
R1=(64*C2-C1)/63.0;
T1=T2;
T2=T1/2.0+t(a,b,4);
S1=S2;
S2=(4*T2-T1)/3.0;
C1=C2;
C2=(16*S2-S1)/15.0;
R2=(64*C2-C1)/63.0;/*先直接求出前两项R1,R2*/
for(k=4;fabs(R1-R2)>=Error;)/*不满足误差要求,再循环计算*/
{
k++;
T1=T2,T2=T1/2.0+t(a,b,k),S1=S2,S2=(4*T2-T1)/3.0,C1=C2,C2=(16*S2-S1)/15.0,R1=R2,R2=(64*C2-C1)/63.0;
}
printf("PI=%.12f\n",R2);
}
/*runge.c*/
floatf(floatx,floaty)/*y'=f(x)*/
{
return(x*pow(y,1.0/3));
}
voidrunge(floata,floatb,floatYo,floath)/*四阶runge_kutta*/
{
floatx0=a,y0=Yo,y1,k1,k2,k3,k4;
intn=(b-a)/h,i;
for(i=1;i<=n;i++)
{
k1=h*f(x0,y0);
k2=h*f(x0+h/2,y0+k1/2);
k3=h*f(x0+h/2,y0+k2/2);
k4=h*f(x0+h,y0+k3);
y1=y0+(k1+2*k2+2*k3+k4)/6;
y0=y1;
x0=a+i*h;
}
printf("y(%.3f)=%f\n",b,y1);
}
voidrunge_kutta()
{
floata=1,b=2,y0=1,h;
charc;
while
(1){
printf("\ninputsteplengthh=");
scanf("%f",&h);getchar();
printf("Whenh=%.3f,",h);
runge(a,b,y0,h);
printf("\n\ncontinue?
('Y'or'N'):
");
c=getchar();
if(c=='N'||c=='n')break;
}
}
/*main.c*/
#include"stdio.h"
#include"conio.h"
#include"math.h"
#defineError5e-9/*自定义romberg误差限*/
#include"lagrange.c"/*多文件运行*/
#include"romberg.c"
#include"runge.c"
main()
{
intchoice;
while
(1){
printf("*1---Lagrange*\n");
printf("*2---Romberg*\n");
printf("*3---Runge_kutta*\n");
printf("*0---Quit*\n");
do{/*选择lagrange插值或者romberg算法或者Runge_kutta*/
printf("Inputyourchoice(0-3):
");
scanf("%d",&choice);getchar();
}while(choice<0||choice>3);/*选择错误,继续输入*/
switch(choice)
{
case1:
lagrange();break;/*执行lagrange.c的lagrange()函数*/
case2:
romberg();break;/*执行romberg.c的romberg()函数*/
case3:
runge_kutta();break;/*执行runge.c的runge_kutta()函数*/
case0:
exit(0);
}
}
}