埃尔米特(Hermite)插值
- 格式:doc
- 大小:33.00 KB
- 文档页数:5
实验二埃尔米特(Hermite)插值一、实验目的:1.掌握埃尔米特插值算法原理;2.使用C语言编程实现埃尔米特插值算法。
二、实验准备:阅读《数值分析》2.4节二、实验要求:某人从甲地开车去乙地,每隔一段时间对行车距离和速率进行一次采样,得到在n+1 个采样时刻点t i 的里程s i和速率v i(i=0, 1, ..., n)。
要求编程构造埃尔米特插值多项式H2n+1(t),满足H2n+1(t i)=s i,H'2n+1(t i)=v i,对所有i=0, 1, ..., n成立,并据此计算m个给定时刻的里程和速率。
函数接口定义:void Hermite_Interpolation( int N, double t[], double s[], double v[], int m, double ht[], double hs[], double hv[] );其中N为采样点个数(注意这个N不是公式中的最大下标n,而是等于n+1),采样时刻点t i、里程s i、速率v i分别通过t、s、v传入;m是需要估算的给定时刻的个数,ht传入给定的时刻点,相应计算出的里程和速率应分别存储在hs和hv中。
裁判程序如下:裁判输入数据:20.0 1.00.0 1.00.0 0.050.0 0.2 0.5 0.8 1.030.0 0.5 1.0100.0 170.0 200.030.0 150.0 0.050.0 0.25 0.5 0.75 1.050.0 1.0 2.0 3.0 4.00.0 60.0 160.0 260.0 300.05.0 70.0 100.0 120.0 20.0100.5 1.0 1.5 2.0 2.5 3.0 3.5 3.8 3.95 4.0标准输出数据:0.0000 0.1040 0.5000 0.8960 1.00000.0000 0.9600 1.5000 0.9600 0.0000100.0000 127.9297 170.0000 195.9766 200.000030.0000 165.4688 150.0000 52.9688 0.000030.2222 60.0000 105.9303 160.0000 206.3438 260.0000 307.9764 305.7687 299.9796 300.000062.6024 70.0000 109.0488 100.0000 92.9745 120.0000 41.2374 -44.8421 -16.2783 20.0000#include<stdio.h>#define MAXN 5 /* 最大采样点个数 */#define MAXM 10 /* 最大估算点个数 */void Hermite_Interpolation( int N, double t[], double s[], double v[], int m, double ht[], double hs[], double hv[] ){double l[10],p[10],h1[10],h2[10],x,ll[10],pp[10];int kk;for(kk=0;kk<m;kk++){x=ht[kk];hs[kk]=0;hv[kk]=0;int i;for(i=0;i<N;i++){l[i]=1;ll[i]=1;int j;for(j=0;j<N;j++){if(i!=j){l[i]=l[i]*(x-t[j])/(t[i]-t[j]);}}p[i]=0;pp[i]=0;int k;for(k=0;k<N;k++){if(i!=k){p[i]=p[i]+l[i]/(x-t[k]);pp[i]=pp[i]+ll[i]/(t[i]-t[k]);}}h1[i]=(1-2*pp[i]*(x-t[i]))*l[i]*l[i];h2[i]=(x-t[i])*l[i]*l[i];hs[kk]=hs[kk]+s[i]*h1[i]+v[i]*h2[i];int kkk;for(kkk=0;kkk<N;kkk++){if(x==t[kkk])break;}if(x==t[kkk])hv[kk]=v[kkk];elsehv[kk]=hv[kk]+s[i]*(2*p[i]*l[i]-4*l[i]*p[i]*(x-t[i])*pp[i]-2*pp[i]*l[ i]*l[i])+v[i]*(l[i]*l[i]+2*l[i]*p[i]*(x-t[i]));}}}int main(){int N, m;double t[MAXN], s[MAXN], v[MAXN]; /* 用于构造的数据 */double ht[MAXM], hs[MAXM], hv[MAXM]; /* 用估算的数据 */int i;while ( scanf("%d", &N) != EOF ) {for ( i=0; i<N; i++ )scanf("%lf", &t[i]);for ( i=0; i<N; i++ )scanf("%lf", &s[i]);for ( i=0; i<N; i++ )scanf("%lf", &v[i]);scanf("%d", &m);for ( i=0; i<m; i++ )scanf("%lf", &ht[i]);Hermite_Interpolation( N, t, s, v, m, ht, hs, hv );for ( i=0; i<m; i++ )printf("%.4lf ", hs[i]);printf("\n");for ( i=0; i<m; i++ )printf("%.4lf ", hv[i]);printf("\n\n");}return 0; }。
埃尔米特插值5.4.1 问题的提出面讨论的拉格朗日和牛顿插值多项式的插值条件只要求在插值节点上,插 值函数与被插值函数的函数值相等,即)(i n x L =f(i x )和n N (i x )=f(i x ),有时 不仅要求插值多项式在插值节点上与被插值函数的函数值相等,还要插值多项式的导数在这些 点上被插函数的导数值相等,即要求满足插值条件:n i x f x H x f x H i i n i i n ,...,1,0,(')('),()()1212===++ (5.4.1)的次数不超过 2n+1的插值多项式12+n H ,这就是埃尔米特 (Hermite) 插值问题。
定义:假设在区间【α,b 】上给定了n 个互不相同的点x 1,x 2,…,x n 以及一张数表(*)记m=α1+α2+…+αn 。
早在 1878年C.埃尔米特就证明:存在惟一的次数不高于m-1的代数多项式H n (x ),使得,H n (x )为表(*)的以为结点组的埃尔米特插值多项式。
如果定义在【α,b 】上的函数ƒ(x )在x k (k =1,2,…,n )处有αk-1阶导数,并取,则称相应的H n (x )为ƒ(x )的以为结点组的(α1,α2,…,αn )阶埃尔米特插值多项式。
作为特殊情况,若诸αk 都为1,则H n (x )就是ƒ(x )的拉格朗日插值多项式;若n =1,则H n (x )为ƒ(x )的α1-1阶泰勒多项式。
最使人们注意的是诸αk 都为2的情况,这时H n (x )为次数不高于2n -1的代数多项式。
如果写H n (x )可表示为在这种情况下,常取,而给以适当的限制。
5.4.2三次埃尔米特插值我们考虑只有两个节点的三次埃尔米特插值。
设插值点为(0x ,0y ),(1x ,1y ),要求一次数不超过3的多项式)(3x H ,满足下列条件:i i i i m x H y x H ==)(',)(33 i=0,1(5.4.2) 式中i m =f ′(i x ),i=01。
实验二埃尔米特(Hermite)插值
一、实验目的:
1.掌握埃尔米特插值算法原理;
2.使用C语言编程实现埃尔米特插值算法。
二、实验准备:
阅读《数值分析》2.4节
二、实验要求:
某人从甲地开车去乙地,每隔一段时间对行车距离和速率进行一次采样,得到在n+1 个采样时刻点t i 的里程s i和速率v i(i=0, 1, ..., n)。
要求编程构造埃尔米特插值多项式H2n+1(t),满足H2n+1(t i)=s i,
H'2n+1(t i)=v i,对所有i=0, 1, ..., n成立,并据此计算m个给定时刻的里程和速率。
函数接口定义:
void Hermite_Interpolation( int N, double t[], double s[], double v[], int m, double ht[], double hs[], double hv[] );
其中N为采样点个数(注意这个N不是公式中的最大下标n,而是等于n+1),采样时刻点t i、里程s i、速率v i分别通过t、s、v传入;m是需要估算的给定时刻的个数,ht传入给定的时刻点,相应计算出的里程和速率应分别存储在hs和hv中。
裁判程序如下:
裁判输入数据:
2
0.0 1.0
0.0 1.0
0.0 0.0
5
0.0 0.2 0.5 0.8 1.0
3
0.0 0.5 1.0
100.0 170.0 200.0
30.0 150.0 0.0
5
0.0 0.25 0.5 0.75 1.0
5
0.0 1.0 2.0 3.0 4.0
0.0 60.0 160.0 260.0 300.0
5.0 70.0 100.0 120.0 20.0
10
0.5 1.0 1.5 2.0 2.5 3.0 3.5 3.8 3.95 4.0
标准输出数据:
0.0000 0.1040 0.5000 0.8960 1.0000
0.0000 0.9600 1.5000 0.9600 0.0000
100.0000 127.9297 170.0000 195.9766 200.0000
30.0000 165.4688 150.0000 52.9688 0.0000
30.2222 60.0000 105.9303 160.0000 206.3438 260.0000 307.9764 305.7687 299.9796 300.0000
62.6024 70.0000 109.0488 100.0000 92.9745 120.0000 41.2374 -44.8421 -16.2783 20.0000
#include<stdio.h>
#define MAXN 5 /* 最大采样点个数 */
#define MAXM 10 /* 最大估算点个数 */
void Hermite_Interpolation( int N, double t[], double s[], double v[], int m, double ht[], double hs[], double hv[] )
{
double l[10],p[10],h1[10],h2[10],x,ll[10],pp[10];
int kk;
for(kk=0;kk<m;kk++)
{
x=ht[kk];hs[kk]=0;hv[kk]=0;
int i;
for(i=0;i<N;i++)
{
l[i]=1;ll[i]=1;
int j;
for(j=0;j<N;j++)
{
if(i!=j)
{
l[i]=l[i]*(x-t[j])/(t[i]-t[j]);
}
}
p[i]=0;pp[i]=0;
int k;
for(k=0;k<N;k++)
{
if(i!=k)
{
p[i]=p[i]+l[i]/(x-t[k]);
pp[i]=pp[i]+ll[i]/(t[i]-t[k]);
}
}
h1[i]=(1-2*pp[i]*(x-t[i]))*l[i]*l[i];
h2[i]=(x-t[i])*l[i]*l[i];
hs[kk]=hs[kk]+s[i]*h1[i]+v[i]*h2[i];
int kkk;
for(kkk=0;kkk<N;kkk++)
{
if(x==t[kkk])
break;
}
if(x==t[kkk])
hv[kk]=v[kkk];
else
hv[kk]=hv[kk]+s[i]*(2*p[i]*l[i]-4*l[i]*p[i]*(x-t[i])*pp[i]-2*pp[i]*l[ i]*l[i])+v[i]*(l[i]*l[i]+2*l[i]*p[i]*(x-t[i]));
}
}
}
int main()
{
int N, m;
double t[MAXN], s[MAXN], v[MAXN]; /* 用于构造的数据 */
double ht[MAXM], hs[MAXM], hv[MAXM]; /* 用估算的数据 */
int i;
while ( scanf("%d", &N) != EOF ) {
for ( i=0; i<N; i++ )
scanf("%lf", &t[i]);
for ( i=0; i<N; i++ )
scanf("%lf", &s[i]);
for ( i=0; i<N; i++ )
scanf("%lf", &v[i]);
scanf("%d", &m);
for ( i=0; i<m; i++ )
scanf("%lf", &ht[i]);
Hermite_Interpolation( N, t, s, v, m, ht, hs, hv );
for ( i=0; i<m; i++ )
printf("%.4lf ", hs[i]);
printf("\n");
for ( i=0; i<m; i++ )
printf("%.4lf ", hv[i]);
printf("\n\n");
}
return 0; }。