计算方法实验报告册.docx
- 文档编号:28206112
- 上传时间:2023-07-09
- 格式:DOCX
- 页数:44
- 大小:379.80KB
计算方法实验报告册.docx
《计算方法实验报告册.docx》由会员分享,可在线阅读,更多相关《计算方法实验报告册.docx(44页珍藏版)》请在冰豆网上搜索。
计算方法实验报告册
实验一——插值方法
实验学时:
4
实验类型:
设计
实验要求:
必修
一实验目的
通过本次上机实习,能够进一步加深对各种插值算法的理解;学会使用用三种类型的插值函数的数学模型、基本算法,结合相应软件(如VC/VB/Delphi/Matlab/JAVA/TurboC)编程实现数值方法的求解。
并用该软件的绘图功能来显示插值函数,使其计算结果更加直观和形象化。
二实验内容
通过程序求出插值函数的表达式是比较麻烦的,常用的方法是描出插值曲线上尽量密集的有限个采样点,并用这有限个采样点的连线,即折线,近似插值曲线。
取点越密集,所得折线就越逼近理论上的插值曲线。
本实验中将所取的点的横坐标存放于动态数组
中,通过插值方法计算得到的对应纵坐标存放于动态数组
中。
以VisualC++.Net2005为例。
本实验将Lagrange插值、Newton插值和三次样条插值实现为一个C++类CInterpolation,并在Button单击事件中调用该类相应函数,得出插值结果并画出图像。
CInterpolation类为
classCInterpolation
{
public:
CInterpolation();//构造函数
CInterpolation(float*x1,float*y1,intn1);//结点横坐标、纵坐标、下标上限
~CInterpolation();//析构函数
…………
…………
intn,N;//结点下标上限,采样点下标上限
float*x,*y,*X;//分别存放结点横坐标、结点纵坐标、采样点横坐标
float*p_H,*p_Alpha,*p_Beta,*p_a,*p_b,*p_c,*p_d,*p_m;//样条插值用到的公有指针,分别存放
,
,
,
,
,
,
和
};
其中,有参数的构造函数为
CInterpolation(float*x1,float*y1,intn1)
{
//动态数组x1,y1中存放结点的横、纵坐标,n1是结点下标上限(即n1+1个结点)
n=n1;
N=x1[n]-x1[0];
X=newfloat[N+1];
x=newfloat[n+1];
y=newfloat[n+1];
for(inti=0;i<=n;i++)
{
x[i]=x1[i];
y[i]=y1[i];
}
for(inti=0;i<=N;i++)
X[i]=x[0]+i;
}
2.1Lagrange插值
,其中
对于一个自变量
,要求插值函数值
,首先需要计算对应的Lagrange插值基函数值
floatl(floatxv,inti)//求插值基函数
的值
{
floatt=1;
for(intj=0;j<=n;j++)
if(j!
=i)
t=t*(xv-x[j])/(x[i]-x[j]);
returnt;
}
调用函数l(floatx,inti),可求出
floatp_l(floatx)//求
在一个点的插值结果
{
floatt=0;
for(inti=0;i<=n;i++)
t+=y[i]*l(x,i);
returnt;
}
调用p_l(floatx)可实现整个区间的插值
float*Lagrange()//求整个插值区间上所有采样点的插值结果
{
float*Y=newfloat[N+1];
for(intk=0;k<=N;k++)
Y[k]=p_l(x[0]+k*h);
returnY;
}
2.2Newton插值
,
其中
,
对于一个自变量
,要求插值函数值
,首先需要计算出
和
float*f()
{
//该函数的返回值是一个长度为n+1的动态数组,存放各阶差商
}
floatw(floatx,inti)
{
//该函数计算
}
在求
的函数中调用*f()得到各阶差商,然后在循环中调用w(floatx)可得出插值结果
floatp_n(floatx)
{
//该函数计算
在一点的值
}
调用p_n(floatx)可实现整个区间的插值
float*Newton()
{
//该函数计算出插值区间内所有点的值
}
2.3三次样条插值
三次样条插值程序可分为以下四步编写:
(1)计算结点间的步长
、
、
;
(2)利用
、
、
产生三对角方程组的系数矩阵和常数向量;
(3)通过求解三对角方程组,得出中间结点的导数
;
(4)对自变量x,在对应区间
上,使用Hermite插值;
(5)调用上述函数,实现样条插值。
将每步写成函数:
(1)
voidGetH(void)
{
//该函数计算数组
}
voidGetAlpha(void)
{
//该函数计算数组
}
voidGetBeta(void)
{
//该函数计算数组
}
(2)
voidGeta(void)
{
//该函数计算数组下对角线
}
voidGetb(void)
{
//该函数计算数组主对角线
}
voidGetc(void)
{
//该函数计算数组上对角线
}
voidGetd(void)
{
//该函数计算方程组右端常数项
}
(3)
float*Chasing(float*pa,float*pb,float*pc,float*pd,intn)
{
//追赶过程,计算各点斜率
}
(4)
floatF0(floatx)
{
//该函数计算函数
的值
}
floatF1(floatx)
{
//该函数计算函数
的值
}
floatP0(floatx)
{
//该函数计算函数
的值
}
floatP1(floatx)
{
//该函数计算函数
的值
}
调用上述函数,实现三次样条插值
float*Cubic_Spline()
{
//该函数计算所有点的插值结果
}
三实验组织运行要求
实验前,由任课教师落实实验任务,每个学生事先编写好算法设计源程序代码。
集中上机、调试并通过计算机图形可视化演示操作实例来测试、验证所学的数值分析理论。
四实验条件
为每个学生提供一台具有WINDOWS98/XP/NT/2000操作系统的计算机;同时提供VC++/VB/JAVA/TC等集成语言开发环境来编程设计计算方法的上机实验。
五实验步骤
1.根据实验内容和算法流程图预先编好程序初稿,上机调试、运行,输出正确的结果。
2.三种类型的插值函数所生成的图形要显示在同一坐标轴上,并用三种不同的颜色分别表示出来。
3.分析它们的运行结果,并比较三种插值函数各自不同的特点。
4.实验完毕后提交实验报告
六实验程序
NInterpolation.cpp
#include"stdafx.h"
#include"NInterpolation.h"
NInterpolation:
:
NInterpolation(void)
{
}
NInterpolation:
:
NInterpolation(double*x,double*y,intn)
{
this->n=n;
this->x=newdouble[n+1];
this->y=newdouble[n+1];
for(inti=0;i<=n;i++)
{
this->x[i]=x[i];
this->y[i]=y[i];
}
N=x[n]-x[0];
X=newdouble[N+1];
Y=newdouble[N+1];
for(inti=0;i<=N;i++)
X[i]=x[0]+i;
a=newdouble[n+1];
for(intk=0;k<=n;k++)
{
doublet=0;
for(inti=0;i<=k;i++)
{
doublem=1;
for(intj=0;j<=k;j++)
{
if(j==i)
continue;
else
m*=(x[i]-x[j]);
}
t+=y[i]/m;
}
a[k]=t;
}
}
NInterpolation:
:
~NInterpolation(void)
{
}
voidNInterpolation:
:
Netwon(void)
{
for(inti=0;i<=N;i++)
{
Y[i]=0;
for(intj=0;j<=n;j++)
{
Y[i]+=((l(X[i],j)*a[j]));
}
}
}
doubleNInterpolation:
:
l(doublemx,intp)
{
doublem=1;
for(inti=0;i
{
m*=(mx-x[i]);
}
returnm;
}
ZInterpolation.cpp
#include"StdAfx.h"
#include"ZInterpolation.h"
ZInterpolation:
:
ZInterpolation(void)
{
}
ZInterpolation:
:
ZInterpolation(double*x,double*y,intn)
{
this->n=n;
this->x=newdouble[n+1];
this->y=newdouble[n+1];
for(inti=0;i<=n;i++)
{
this->x[i]=x[i];
this->y[i]=y[i];
}
N=x[n]-x[0];
X=newdouble[N+1];
Y=newdouble[N+1];
for(inti=0;i<=N;i++)
X[i]=x[0]+i;
}
ZInterpolation:
:
~ZInterpolation(void)
{
}
doubleZInterpolation:
:
l(doublemx,inti)
{
doublet=1;
for(intj=0;j<=n;j++)
if(j==i)
continue;
else
t*=(mx-x[j])/(x[i]-x[j]);
returnt;
}
doubleZInterpolation:
:
L(doublemx)
{
doublet=0;
for(inti=0;i<=n;i++)
t+=y[i]*l(mx,i);
returnt;
}
voidZInterpolation:
:
lagrange(void)
{
for(inti=0;i<=N;i++)
Y[i]=L(X[i]);
}
x=[1234];
y=[12-834100];
xi=1:
0.1:
4;
yi=interp1(x,y,xi,'spline');
plot(x,y,'o',xi,yi);
七实验结果
NInterpolationZInterpolation
Cubic_Spline
上述是第一个实验——插值方法程序的构思和编写过程。
将其简单概括,可分为以下几步:
(1)按照本实验指导书的开篇——“集成开发环境VisualC++.Net的使用”中的第一部分——“开发环境介绍”建立项目。
(2)为项目添加一个类,在该类中编写插值算法。
该类需要一个有参数的构造函数将类外的插值条件数据传递到类中。
(3)按照“集成开发环境VisualC++.Net的使用”所述为项目添加对话框双击事件响应程序,将鼠标双击的坐标存放于数组或线性表中,用于插值,并将双击的点用小圆圈标出。
(4)在对话框上添加一个Button(按钮),双击改按钮,添加响应程序,调用拉格朗日插值函数,并将得到的相邻插值点用直线连接起来。
连线的方法在“集成开发环境VisualC++.Net的使用”有介绍。
(5)用与(4)类似的方法添加牛顿插值和三次样条插值的Button和相应的响应程序。
对于插值结点的存储,可以采用线性表。
为了通过插值结点确定插值区间,可将这些点按照横坐标递增排序。
务必熟练实验一程序编写的每一步骤,做到能够从头至尾独立编写。
在项目的建立、画图、类的添加和编程思维各方面,后面的四个实验与实验一都是类似的。
本实验指导书对后面的四个实验不再如此赘述。
实验二——数值积分
实验学时:
2
实验类型:
设计
实验要求:
必修
一实验目的
通过该课程实习,学会使用数值积分的各种方法求解定积分计算的问题,体会各种方法的精度差异。
二实验内容
本实验将梯形法的递推化和龙贝格算法编写为类CIntegration,在工程中调用该类得出积分结果并画出区间二分图像。
首先画出被积函数图像,并储存被积函数在图像中每个像素对应的采样点的横坐标(存放于float型指针p_X中)和纵坐标(存放于int型指针p_Y中);然后调用CIntegration类中相应函数,计算积分结果;最后将x轴上的区间二分点与其对应的被积函数值的点连线。
CIntegration有公有变量和指针floata,b,h,*x;intn和带参数的构造函数
CIntegration:
:
CIntegration(floatma,floatmb)
{
a=ma;//a、b分别为积分区间左右端点
b=mb;
n=1;//区间二分个数
h=b-a;//步长
x=newfloat[n+1];//存放区间二分点
x[0]=a;
x[1]=b;
}
另需被积函数
floatCIntegration:
:
f(floatx)
{
floatmTemp=sin(x);//可替换为其他函数
returnmTemp;
}
绘制函数图像时,需要将图像按照比例放大。
2.1梯形法的递推化
梯形法递推化公式为
该过程是下列过程的往复循环
(1)求已有各区间中点函数值的和
;
(2)求积分值
。
(3)区间二分,即更新结点,并将步长
减半。
要实现该算法过程,需要先编写下面两个函数
floatCIntegration:
:
Sum(void)
{
//该函数求
的值
}
voidCIntegration:
:
Divide(void)
{
//该函数实现区间二分和步长更新
float*px=newfloat[2*n+1];
for(inti=0;i { px[2*i]=x[i]; px[2*i+1]=(x[i]+x[i+1])/2; } px[2*n]=x[n]; deletex; x=px; n=n*2; h=h/2; } 为了后面编程的方便,可将单次二分过程写为函数 floatCIntegration: : T1ToT2(floatT1) { } 最后,调用T1ToT2,可实现梯形法递推化的函数 floatCIntegration: : Trapezium_Recurrence(floate) { } 在后面的Romberg函数中,还需要用到迭代一定次数的梯形法递推函数 floatCIntegration: : Trapezium_Recurrence(intN) { } 2.2龙贝格算法 …… …… …… …… 其中 调用梯形法递推函数Trapezium_Recurrence(intN)可以很方便的实现单次龙贝格算法的函数 floatCIntegration: : R1(float*T) { } 调用函数R1可实现迭代的龙贝格函数 floatCIntegration: : Romberg(floate) { } 三实验组织运行要求 实验前,由任课教师落实实验任务,每个学生事先编写好算法设计源程序代码。 集中上机、调试并通过计算机图形可视化演示操作实例来测试、验证所学的数值分析理论。 四实验条件 为每个学生提供一台具有WINDOWS98/XP/NT/2000操作系统的计算机;同时提供VC++/VB/JAVA/TC等集成语言开发环境来编程设计计算方法的上机实验。 五实验步骤 1、根据实验内容和算法流程图预先编好程序初稿,上机调试、运行。 2、用绘图函数绘出曲边梯形的面积并计算其值并输出正确的结果。 3、测试、分析它们的运行结果,比较两种方法的精度差异。 4、实验完毕后提交实验报告。 六实验程序 Trapezium_Recurrence.cpp //Trapezium_Recurrence.cpp: 定义控制台应用程序的入口点。 #include"stdafx.h" #include"math.h" #include usingnamespacestd; doublef(doublex) { return1/x; } doublesum(intn,doublea,doubleb) { doublet=(b-a)/n; doubles=0; for(inti=0;i { s+=f(a+t+i*((b-a)/(n/2))); } returns; } doubleTrapezium_Recurrence(doublea,doubleb,doublee) { doublet=b-a; doubleR=t/2*(f(a)+f(b)); for(inti=2;;i*=2) { doubletemp=R; R=1./2*R+(t/i)*sum(i,a,b); if(abs(R-temp)<=e) break; else continue; } returnR; } int_tmain(intargc,_TCHAR*argv[]) { doublea=1,b=2,e=0.0001; doubleresult=Trapezium_Recurrence(a,b,e); cout< system("pause"); return0; } Romberg.cpp //Romberg.cpp: 定义控制台应用程序的入口点。 #include"stdafx.h" #include"math.h" #include usingnamespacestd; doublef(doublex) { return1/x; } doubleRomberg(doublea,doubleb,doublee) { intk=1; doubleh=b-a; doubleT1=h/2*(f(a)+f(b)); doubleT2=0,S1=0,S2=0,C1=0,C2=0,R1=0,R2=0; for(;;k++,h=h/2,T1=T2,S1=S2) { doubles=0,x=a+h/2; for(;x T2=T1/2+h/2*s; S2=T2+(T2-T1)/3; if(k==1) continue; else C2=S2+(S2-S1)/15; if(k==2) { C1=C2; continue; } else R2=C2+(C2-C1)/63; if(k==3) { R1=R2; C1=C2; continue; } else if(abs(R2-R1)>=e) { R1=R2; C1=C2; continue; } else returnR2; } } int_tmain(intargc,_TCHAR*argv[]) { doublea=1,b=2,e=0.0001; doubleresult=Romberg(a,b,e); cout< system("pause"); return0; } 七实验结果 Trapezium_Recurrence Romberg 实验三——微分方程 实验学时: 2 实验类型: 综合/设计 实验要求: 必修 一实验目的 通过本次实验,熟悉求解常微分方程初值问题的有关方法和理论,主要是欧拉法、改进欧拉法、四阶龙格库塔法,学会编制这三种方法的计算程序。 体会这三种解法的功能、优缺点及适用场合。 二实验内容 本实验将欧拉法、改进欧拉法和经典四阶龙哥库塔法编写为一个类CDifferential_Equation,调用该类实现一阶微分方程初值问题的求解,并画出解函数的图像。 CDifferential_Equation的框架如下 classCDifferential_Equation { public: CDifferential_Equation(floatma,floatmb,floatmh,floatmy0); ~CDifferential_Equation(void); floatf(floatx,floaty); voidEuler(void);//欧拉法 voidEuler_Improved(void);//改进欧拉法 voidClassical_Forth_Order_Runge_Kutta(void);//经典四阶龙哥库塔法 floata,b,h,y0;//分别为区间左端点、区间右端点、步长 float*x,*y;//存放各个结点和横、纵坐标 intn;//结点个数,构造函数中得到 }; 其中有参数的构造函数为 CDifferential_Equation: : CDifferential_Equation(floatma,floatmb,floatmh,floatmy0) { a=ma;b=mb;h=mh; n=(b-a)/h; x=newfloat[n+1]; y=newfloat[n+1]; for(inti=0;i<=n;i++) x[i]=a+h*i; y[0]=my0; } 三实验组织运行要求 实验前,由任课教师落实实验任务,每个学生事先编写好算法设计源程序代码。 集中上机、调试并通过计算机图形可视化演示操作实例来测试、验证所学的数值分析
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算方法 实验 报告