发布时间 : 星期一 文章计算方法实验报告册更新完毕开始阅读
实验一——插值方法
实验学时:4
实验类型:设计 实验要求:必修
一 实验目的
通过本次上机实习,能够进一步加深对各种插值算法的理解;学会使用用三种类型的插值函数的数学模型、基本算法,结合相应软件(如VC/VB/Delphi/Matlab/JAVA/Turbo C)编程实现数值方法的求解。并用该软件的绘图功能来显示插值函数,使其计算结果更加直观和形象化。
二 实验内容
通过程序求出插值函数的表达式是比较麻烦的,常用的方法是描出插值曲线上尽量密集的有限个采样点,并用这有限个采样点的连线,即折线,近似插值曲线。取点越密集,所得折线就越逼近理论上的插值曲线。本实验中将所取的点的横坐标存放于动态数组于动态数组Y[n]中。
以Visual C++.Net 2005为例。
本实验将Lagrange插值、Newton插值和三次样条插值实现为一个C++类CInterpolation,并在Button单击事件中调用该类相应函数,得出插值结果并画出图像。CInterpolation类为 class CInterpolation { public:
CInterpolation();//构造函数
CInterpolation(float *x1, float *y1, int n1);//结点横坐标、纵坐标、下标上限 ~ CInterpolation();//析构函数 ………… …………
int n, N;//结点下标上限,采样点下标上限
float *x, *y, *X;//分别存放结点横坐标、结点纵坐标、采样点横坐标
float *p_H,*p_Alpha,*p_Beta,*p_a,*p_b,*p_c,*p_d,*p_m;//样条插值用到的公有指针,分别存放
X[n]中,通过插值方法计算得到的对应纵坐标存放
hi,?i,?i,ai,bi,ci,di和mi
};
其中,有参数的构造函数为
CInterpolation(float *x1, float *y1, int n1) {
//动态数组x1,y1中存放结点的横、纵坐标,n1是结点下标上限(即n1+1个结点) n=n1;
N=x1[n]-x1[0]; X=new float[N+1]; x=new float[n+1]; y=new float[n+1];
for(int i=0;i<=n;i++) {
x[i]=x1[i]; y[i]=y1[i]; }
for(int i=0;i<=N;i++) X[i]=x[0]+i; }
2.1 Lagrange插值
Pn(x)??yili(x),其中li(x)?i?0nj?0,j?n?nx?xjxi?xj
对于一个自变量x,要求插值函数值Pn(x),首先需要计算对应的Lagrange插值基函数值li(x) float l(float xv,int i) //求插值基函数li(x)的值 {
float t=1;
for(int j=0;j<=n;j++) if(j!=i)
t=t*(xv-x[j])/(x[i]-x[j]); return t; }
调用函数l(float x,int i),可求出Pn(x)
float p_l(float x) //求Pn(x)在一个点的插值结果 {
float t=0;
for(int i=0;i<=n;i++) t+=y[i]*l(x,i); return t; }
调用p_l(float x)可实现整个区间的插值
float *Lagrange() //求整个插值区间上所有采样点的插值结果 {
float *Y=new float[N+1]; for(int k=0;k<=N;k++) Y[k]=p_l(x[0]+k*h); return Y; } 2.2
Newton插值
Pn(x)??f(x0,x1,i?0nxi)?i(x),
?1,i?0?其中?i(x)??i?1,f(x0,x1,(x?x),i?0j??j?0?xi)??k?0if(xk)j?0,j?k?n
(xk?xj)对于一个自变量x,要求插值函数值Pn(x),首先需要计算出float *f() {
//该函数的返回值是一个长度为n+1的动态数组,存放各阶差商 }
float w(float x, int i) {
//该函数计算?i(x) }
f(x0,x1,xi)和?i(x)
在求Pn(x)的函数中调用*f()得到各阶差商,然后在循环中调用w(float x)可得出插值结果 float p_n(float x) {
//该函数计算Pn(x)在一点的值 }
调用p_n(float x)可实现整个区间的插值 float *Newton() {
//该函数计算出插值区间内所有点的值 }
2.3 三次样条插值
三次样条插值程序可分为以下四步编写: (1) (2) (3) (4) (5)
计算结点间的步长hii、?i、?i;
利用hii、?i、?i产生三对角方程组的系数矩阵和常数向量; 通过求解三对角方程组,得出中间结点的导数mi; 对自变量x,在对应区间[xi,xi?1]上,使用Hermite插值; 调用上述函数,实现样条插值。
将每步写成函数:
(1)
void GetH(void) {
//该函数计算数组hii
}
void GetAlpha(void) {
//该函数计算数组?i }
void GetBeta(void) {
//该函数计算数组?i }
(2)
void Geta(void) {
//该函数计算数组下对角线ai }
void Getb(void) {
//该函数计算数组主对角线bi }
void Getc(void) {
//该函数计算数组上对角线ci }
void Getd(void) {
//该函数计算方程组右端常数项di }
(3)
float *Chasing(float *pa,float *pb,float *pc,float *pd,int n) {
//追赶过程,计算各点斜率mi }
(4)
float F0(float x) {
//该函数计算函数?0(x)的值 }