计算方法实验报告(高尚版)

  • 格式:doc
  • 大小:582.00 KB
  • 文档页数:42

下载文档原格式

  / 42
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验一——插值方法

实验学时:4

实验类型:设计 实验要求:必修

一 实验目的

通过本次上机实习,能够进一步加深对各种插值算法的理解;学会使用用三种类型的插值函数的数学模型、基本算法,结合相应软件(如VC/VB/Delphi/Matlab/JAVA/Turbo C )编程实现数值方法的求解。并用该软件的绘图功能来显示插值函数,使其计算结果更加直观和形象化。

二 实验内容

通过程序求出插值函数的表达式是比较麻烦的,常用的方法是描出插值曲线上尽量密集的有限个采样点,并用这有限个采样点的连线,即折线,近似插值曲线。取点越密集,所得折线就越逼近理论上的插值曲线。本实验中将所取的点的横坐标存放于动态数组[]X n 中,通过插值方法计算得到的对应纵坐标存放

于动态数组[]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;//样条插值用到的公有指针,分别存放

i h ,i α,i β,i a ,i b ,i c ,i d 和i m

};

其中,有参数的构造函数为

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 插值

()()n

n i i i P x y l x ==∑,其中0,()n

j i j j n

i j

x x l x x x =≠-=

-∏

对于一个自变量x ,要求插值函数值()n P x ,首先需要计算对应的Lagrange 插值基函数值()i l x

float l(float xv,int i) //求插值基函数()i l 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),可求出()n P x

float p_l(float x) //求()n P 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 插值

010

()(,,

)()n

n i i i P x f x x x x ω==∑,

其中101,0

()(),0i i j j i x x x i ω-==⎧⎪

=⎨-≠⎪⎩

∏,010

0,()

(,,

)()

i

k i n

k k j j j k

f x f x x x x x ==≠=-∑

对于一个自变量x ,要求插值函数值()n P x ,首先需要计算出01(,,

)i f x x x 和()i x ω

float *f()

{

//该函数的返回值是一个长度为n +1的动态数组,存放各阶差商 }

float w(float x, int i) {

//该函数计算()i x ω }

在求()n P x 的函数中调用*f()得到各阶差商,然后在循环中调用w(float x)可得出插值结果 float p_n(float x) {

//该函数计算()n P x 在一点的值

}

调用p_n(float x)可实现整个区间的插值 float *Newton() {

//该函数计算出插值区间内所有点的值 }

2.3 三次样条插值

三次样条插值程序可分为以下四步编写:

(1) 计算结点间的步长i hi 、i α、i β;

(2) 利用i hi 、i α、i β产生三对角方程组的系数矩阵和常数向量; (3) 通过求解三对角方程组,得出中间结点的导数i m ; (4)

对自变量x ,在对应区间1[,]i i x x +上,使用Hermite 插值;

(5) 调用上述函数,实现样条插值。 将每步写成函数: (1)

void GetH(void ) {

//该函数计算数组i hi }

void GetAlpha(void ) {

//该函数计算数组i α }

void GetBeta(void ) {

//该函数计算数组i β }

(2)

void Geta(void ) {

//该函数计算数组下对角线i a }

void Getb(void ) {

//该函数计算数组主对角线i b }

void Getc(void ) {

//该函数计算数组上对角线i c }

void Getd(void ) {

//该函数计算方程组右端常数项i d }

(3)

float *Chasing(float *pa,float *pb,float *pc,float *pd,int n) {

//追赶过程,计算各点斜率i m }

(4)

float F0(float x) {

//该函数计算函数0()x ϕ的值 }