三次样条函数

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

计算方法实验报告

1、实验题目

三次样条插函数。

2、实验内容

三次样条插值是建立在Hermite 插值的基础上的。Hermite 插值是在一个区间上的插值,而三次样条插则是建立多个区间上插值,构造一个具有二阶光滑度的曲线,在求出给定点上对应的函数。本实验就是建立一个能根据三次样条插值函数求根的程序。

3、算法思想

给定一个区间,并把它分成n 等份,并且给出了每个结点对就的横坐标和纵坐标。利用程序输出给定插值点对应的值。横坐标设为:X 0, X 1, X 2, X 3, …X n 纵坐标为Y 0, Y 1, Y 2, …Y n ,设插点为u 。则令h k =X k+1-X k ,λk =1-+k k k h h h , μk =11--+k k k h h h , g k =3(1

11--+-+-k k k k k k k k h y y h y y λμ), 其中k=1,2,…,n-1 再根据第一类边界条件则可以确定公式6.16,再根据6.17解出方程中的m 向量,最后代入公式6.8求解。

4、源程序清单

#include

#define N 21/*最大结点个数减一*/

void sanCi()

{

/*定义过程数据变量*/

float x[N],y[N],h[N]; /*横纵坐标及区间长度*/

float rr[N],uu[N],gg[N]; /*计算m 用的中间数组rr 、uu 、gg 分别对应:λ、μ、g 数组*/

float aa[N],bb[N],tt[N]; /*矩阵分解时用到的中间变量aa、bb、tt分别对应:α、β数组以及A=LU时中间矩阵*/

float mm[N]; /*最后要用到的系数m*/

int n,k,kv,chose; /* n为实际结点个数,k为下标,kv为最后确定k的值*/

float s,u; /*最后计算u对应的值*/

printf("请输入区间段数:");

scanf("%d",&n); /*输入结点个数*/

/*输入所有横坐标:*/

printf("输入所有横坐标:");

for(k=0; k<=n; k++)

scanf("%f",&x[k]);

/*输入对应纵坐标:*/

printf("输入对应纵坐标:");

for(k=0; k<=n; k++)

scanf("%f",&y[k]);

for(k=0; k

h[k] = x[k+1] - x[k];

/*构建Am=f中的行列式A*/

for(k=1; k

{

rr[k] = h[k]/(h[k]+h[k-1]); /*计算λ[k]*/

uu[k] = h[k-1]/(h[k]+h[k-1]); /*计算μ[k]*/

gg[k] = 3 * (uu[k]*(y[k+1]-y[k])/h[k] + rr[k]*(y[k]-y[k-1])/h[k-1]); /*计算g[k]*/

}

/* g[1] = λ[1]*f'[0] */

/* g[n-1] = μ[n-1]*f'[n] */

gg[1] = gg[1] - rr[1]/x[0];

gg[n-1] = gg[n-1] -uu[n-1]/x[n];

/*作A=LU分解*/

aa[1] = 2;

bb[1] = uu[1]/aa[1];

for(k=2; k

{

aa[k] = (float)2.0 - rr[k]*bb[k-1];

bb[k] = uu[k]/aa[k];

}

/*通过LT=G计算中间矩阵T*/

tt[1] = gg[1]/aa[1];

for(k=2; k

tt[k] = (gg[k]-rr[k]*tt[k-1])/aa[k];

/*根据第一类边界条件所得*/

mm[n] = 1/x[n];

mm[0] = 1/x[0];

/*通过UM=T计算M*/

mm[n-1] = tt[n-1];

for(k=n-2; k>=1; k--)

mm[k] = tt[k]-bb[k]*mm[k+1];

do{

printf("输入插值点:");

scanf("%f",&u);

/*判断u属于哪个区间x[k],x[k+1]确定k*/

for(k=0; k

{

if( u>=x[k] && u<=x[k+1] )

{

kv = k;

break;

}

}

/*代入u计算值*/

s = (1-2*(u-x[kv])/(-h[kv])) * ((u-x[kv+1])/(-h[kv])) * ((u-x[kv+1])/(-h[kv])) * y[kv];

s = s + (1-2*(u-x[kv+1])/h[kv]) * ((u-x[kv])/h[kv]) * ((u-x[kv])/h[kv]) * y[kv+1];

s = s + (u-x[kv])*((u-x[kv+1])/(-h[kv]))*((u-x[kv+1])/(-h[kv])) * mm[kv];

s = s + (u-x[kv+1])*((u-x[kv])/(-h[kv]))*((u-x[kv])/(-h[kv])) * mm[kv+1];

printf("与%f对应的结点值为%f\n\n",u,s);

printf("还要继续插值吗?(1/0): ");

scanf("%d",&chose);

}while( chose != 0 );

}

void main()

相关文档
最新文档