数值分析实验:Hermite插值

1 题目

题目::人从甲地开车去乙地,每隔一段时间对行车距离和速率进行一次采样,得到在 n + 1 n+1 n+1 个采样时刻点 t i t_i ti 的里程 s i s_i si 和速率 v i ( i = 0 , 1 , . . . , n ) v_i(i=0, 1, ..., n) vii=0,1,...,n

要求::编程构造埃尔米特插值多项式 H 2 n + 1 ( t ) H_{2n+1}(t) H2n+1(t)

满足::
对所有i=0, 1, …, n

{ H 2 n + 1 ( t i ) = s i H 2 n + 1 ′ ( t i ) = v i \left \{\begin{matrix} H_{2n+1}(t_i)=s_i & & \\ H'_{2n+1}(t_i)=v_i & & \end{matrix} \right. {H2n+1(ti)=siH2n+1(ti)=vi

并据此计算 m m m个给定时刻 h t ht ht及其里程 h s hs hs和速率 h v hv hv

函数接口定义::
void Hermite_Interpolation( int N, double t[], double s[], double v[], int m, double ht[], double hs[], double hv[] );

其中 N N N为采样点个数(注意这个 N N N不是公式中的最大下标 n n n,而是等于 n + 1 n+1 n+1

采样时刻点 t i t_i ti、里程 s i s_i si、速率 v i v_i vi分别通过 t 、 s 、 v t、s、v tsv传入;

m m m是需要估算的给定时刻的个数, h t ht ht传入给定的时刻点,相应计算出的里程和速率应分别存储在 h s hs hs h v hv hv中。


2 c++代码实现

2.0 程序目录

伪代码

main.cpp

Hermite_Interpolation.h

input.txt

output.txt

2.1 伪代码

===========================================================================================================

伪代码:Hermite_Interpolation

输入: N N N 个采样时刻点 t i t_i ti 的里程 s i s_i si 和速率 v i ( i = 0 , 1 , . . . , n ) v_i(i=0, 1, ..., n) vii=0,1,...,n, m m m个给定时刻

输出:这 m m m个给定时刻 h t ht ht及其里程 h s hs hs和速率 h v hv hv

===========================================================================================================
00:init h s [ ] hs[] hs[], h v [ ] hv[] hv[], l [ ] l[] l[], p [ ] p[] p[], p p [ ] pp[] pp[], k k k

01:for   k ← 0 k\leftarrow0 k0  to   m m m

02:   x x ← h t [ k ] xx \leftarrow ht[k] xxht[k]

03:  for   i ← 0 i\leftarrow 0 i0  to   N N N

04:     l i ← ∏ j = 0 , j ≠ i N x − t j t i − t j l_i \leftarrow \prod_{j=0,j\neq i}^{N}{\frac{x-t_j}{t_i-t_j}} lij=0,j̸=iNtitjxtj

05:     p i ← ∑ j = 0 , j ≠ i N l i x − t j ; p_i \leftarrow \sum_{j=0,j\neq i}^{N}{\frac{l_i}{x-t_j}}; pij=0,j̸=iNxtjli;

06:     p p i ← ∑ j = 0 , j ≠ i N 1 t i − t j ; pp_i \leftarrow \sum_{j=0,j\neq i}^{N}{\frac{1}{t_i-t_j}}; ppij=0,j̸=iNtitj1;

07:     h 1 i ← [ 1 − 2 ⋅ p p i ⋅ ( x − t i ) ] ⋅ l i 2 ; h1_i \leftarrow [1-2 \cdot pp_i \cdot (x-t_i)] \cdot l_i^2; h1i[12ppi(xti)]li2;

08:     h 2 i ← ( x − t i ) ⋅ l i 2 ; h2_i \leftarrow (x-t_i) \cdot l_i^2; h2i(xti)li2;

09:  end

10:   h s k ← ∑ i = 0 N ( s i ⋅ h 1 i + v i ⋅ h 2 i ) ; hs_{k} \leftarrow \sum_{i=0}^{N}{(s_i \cdot h1_i+v_i \cdot h2_i)}; hski=0N(sih1i+vih2i);

11:  if  find  a a a s.t.  h t k = = t a ht_{k} == t_a htk==ta  then

12:     h v k ← v a hv_{k} \leftarrow v_a hvkva

13:  else

14:     h v k ← ∑ i = 0 N s i ⋅ [ 2 ⋅ l i ⋅ p i − 2 ⋅ p p i ⋅ l i − 4 ⋅ p p i ⋅ ( x − t i ) ⋅ l i ⋅ p i ] + v i ⋅ [ l i 2 + 2 ⋅ l i ⋅ p i ⋅ ( x − t i ) ] hv_k \leftarrow \sum_{i=0}^{N}{s_i \cdot [2 \cdot l_i \cdot p_i - 2 \cdot pp_i \cdot l_i - 4 \cdot pp_i \cdot (x - t_i) \cdot l_i \cdot p_i] + v_i \cdot [l_i^2 + 2 \cdot l_i \cdot p_i \cdot (x - t_i)]} hvki=0Nsi[2lipi2ppili4ppi(xti)lipi]+vi[li2+2lipi(xti)]

15:  end if

16:end

17:return  h s [ ] , h v [ ] hs[], hv[] hs[],hv[]

===========================================================================================================

2.2 main.cpp

#include<stdio.h>
#include<iostream>
using namespace std;

#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[] );

int main()
{
    int N, m;
    double t[MAXN], s[MAXN], v[MAXN]; /* 用于构造的数据 */
    double ht[MAXM], hs[MAXM], hv[MAXM]; /* 用于估算的数据 */
    int i;

    freopen("input.txt", "r", stdin);

    while ( scanf("%d", &N) != EOF ) {
            //可以测试多组数据
            //输入N:n+1个采样点

        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);
            //m个需要估算的给定时刻

        for ( i=0; i<m; i++ )
            scanf("%lf", &ht[i]);

        //重点::利用Hermite插值多项式进行估算
        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");
    }
    fclose(stdin);

  return 0;
}

#include "Hermite_Interpolation.h"

2.3 Hermite_Interpolation.h

#ifndef HERMITE_INTERPOLATION_H_INCLUDED
#define HERMITE_INTERPOLATION_H_INCLUDED
#include<cstdio>

void Hermite_Interpolation( int N, double t[], double s[], double v[], int m, double ht[], double hs[], double hv[] )
{
    double l[MAXM], f[MAXM], h1[MAXM], h2[MAXM], t_x, a[10];

    //遍历每一组要求时刻
    for(int k=0;k<m;k++)
    {
        //初始化
        t_x=ht[k];
        hs[k]=0;
        hv[k]=0;

        //遍历每个采样点
        for(int i=0;i<N;i++)
        {
            //初始化
            l[i] = 1;
            a[i] = 0;

            //遍历每个采样点,求l[i],用于求hs
            for(int j=0;j<N;j++)
            {
                if(i != j)
                {
                    l[i] *= (t_x-t[j])/(t[i]-t[j]);
                    a[i] += 1/(t[i] - t[j]);
                }
            }

            //初始化
            f[i]=0;

            //遍历每个采样点,求f[i],用于求hv
            for(int j=0;j<N;j++)
            {
                if(i!=j)
                    f[i] += l[i]/(t_x-t[j]);
            }

            h1[i] = (1-2*a[i]*(t_x-t[i]))*l[i]*l[i];
            h2[i] = (t_x-t[i])*l[i]*l[i];
            hs[k] = hs[k] + s[i]*h1[i] + v[i]*h2[i];

            int e=0;
            for(;e<N;e++)
            {
                if(t_x==t[e])
                break;
            }

            if(t_x==t[e])
                hv[k]=v[e];
            else
                hv[k]=hv[k] + (2*l[i]*f[i] - 2*a[i]*l[i]*l[i] - 4*a[i]*(t_x-t[i])*l[i]*f[i]) * s[i] + (l[i]*l[i] + 2*l[i]*f[i]*(t_x-t[i])) * v[i];
        }
    }
}


#endif // HERMITE_INTERPOLATION_H_INCLUDED

2.4 input.txt

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

2.5 output.txt

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 

3 难点解析 – Hermite_Interpolation.h

Hermite插值满足 在节点上等于给定函数值 ,而且 在节点上的导数值也等于给定的导数值 。对于高阶导数的情况,Hermite插值多项式比较复杂,在实际情况中,常常遇到的是 函数值与一阶导数给定的情况

在此情况下,对给定的n个节点x1,x2,…,xn的Hermite插值多项式充分理解 二重hermite插值多项式的一般形式 , 并在此基础上,编程实现

尽可能 节约空间 ,并 降低算法复杂 的条件下实现hermite插值多项式( 公式见伪代码 ),最终利用求出的插值多项式求出在 m m m h t [ ] ht[] ht[]时刻下的 h s [ ] hs[] hs[] h v [ ] hv[] hv[]



Author
lance
2018.10.16
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值