计算方法实验报告册 联系客服

发布时间 : 星期一 文章计算方法实验报告册更新完毕开始阅读

实验一——插值方法

实验学时: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)的值 }