Files
worldmodel/research/math/hermite_interpolation.md
gaojie 920439e044
Sync to site1 / sync (push) Has been cancelled
Add presentation slides for OU process and Mehler formula
2026-06-03 04:08:01 +08:00

27 KiB
Raw Permalink Blame History

title, date, draft, tags, categories, description
title date draft tags categories description
Hermite 插值详解 2026-06-02 false
数值分析
插值
Hermite插值
多项式逼近
research
math
从切触条件、构造方法到误差分析,系统讲解 Hermite 插值的理论与应用。

Hermite 插值详解

本文系统讲解数值分析中的 Hermite 插值(Hermite Interpolation,埃尔米特插值)。它是 Lagrange 插值的自然推广:不仅要求插值多项式在节点处与被插函数取相同的函数值,还要求取相同的导数值(一阶乃至更高阶)。这使得插值曲线在节点处不仅"经过"数据点,还与原曲线"相切",从而得到更光滑、更逼真的逼近。


一、引入与动机

1.1 从 Lagrange 插值说起

给定 n+1 个互异节点 x_0, x_1, \dots, x_n 及对应函数值 $f(x_i)$,Lagrange 插值给出唯一的次数 \le n 多项式 $L_n(x)$,使得


L_n(x_i) = f(x_i), \qquad i = 0, 1, \dots, n.

它只匹配函数值。然而在很多实际问题中,我们对曲线"形状"的要求更高,仅匹配函数值是不够的

  • 光滑性不足:Lagrange 插值在节点处的切线方向完全由全局多项式自动决定,可能与真实曲线的斜率相去甚远,导致曲线在节点附近"扭动"。
  • 物理意义缺失:若数据点代表某质点的位置,那么我们往往同时知道该点的速度(即一阶导数)。只匹配位置而丢弃速度信息,是对已知信息的浪费。
  • 拼接不连续:在分段插值中,若相邻段只匹配端点函数值而不匹配导数,则拼接处会出现折角(导数不连续)。

1.2 Hermite 插值的核心思想

Hermite 插值的思想是:在节点处同时匹配函数值与若干阶导数值。最常见的是同时匹配函数值与一阶导数值:


H(x_i) = f(x_i), \qquad H'(x_i) = f'(x_i), \qquad i = 0, 1, \dots, n.

1.3 几何直观:节点处"相切"

考虑两条曲线 y = f(x) 与 $y = H(x)$。如果它们在某点 x_i 满足


H(x_i) = f(x_i) \quad (\text{过同一点}), \qquad H'(x_i) = f'(x_i) \quad (\text{斜率相同}),

那么这两条曲线在 x_i相切(一阶切触,order-1 contact)。如果进一步匹配到二阶导数 $H''(x_i)=f''(x_i)$,则它们在该点的曲率也一致(更高阶的切触)。

一句话概括:Lagrange 插值让曲线"穿过"数据点;Hermite 插值让曲线"贴着"数据点走。


二、问题定义

2.1 一般 Hermite 插值问题

给定 n+1 个互异节点 $x_0, x_1, \dots, x_n$。在每个节点 x_i 处,给定函数值及从一阶到 m_i 阶的导数值:


f(x_i),\ f'(x_i),\ f''(x_i),\ \dots,\ f^{(m_i)}(x_i).

也就是说,节点 x_i 处提供了 m_i + 1 个约束条件(称该节点的重数(multiplicity为 $m_i + 1$)。我们称整数 m_i 为节点 x_i切触阶(order of contact

记总约束数(总自由度)为


N = \sum_{i=0}^{n} (m_i + 1).

目标:求一个次数 \le N-1 的多项式 $H(x)$,满足全部切触条件


H^{(k)}(x_i) = f^{(k)}(x_i), \qquad k = 0, 1, \dots, m_i, \quad i = 0, 1, \dots, n.

2.2 存在唯一性定理

定理(Hermite 插值的存在唯一性) 设节点 x_0, \dots, x_n 互异,切触阶分别为 $m_0, \dots, m_n$,记 $N = \sum_{i=0}^{n}(m_i+1)$。则在给定上述 N 个切触条件下,存在且唯一一个次数 \le N-1 的多项式 H(x) 满足所有条件。

证明(唯一性,反证法) 次数 \le N-1 的多项式构成一个 N 维线性空间(基为 $1, x, \dots, x^{N-1}$),共有 N 个待定系数。切触条件给出 N 个线性方程,于是问题等价于一个 N \times N 的线性方程组。要证明解存在且唯一,只需证明对应齐次问题只有零解。

P(x) 是次数 \le N-1 的多项式,且满足全部齐次条件


P^{(k)}(x_i) = 0, \qquad k = 0, 1, \dots, m_i, \quad i = 0, 1, \dots, n.

则在每个节点 x_i 处,P 及其直到 m_i 阶导数都为零,意味着 x_iP 的至少 m_i + 1 重根。因此 P 的根(计重数)总数至少为


\sum_{i=0}^{n}(m_i + 1) = N.

P 的次数 $\le N-1$,一个非零的 N-1 次多项式至多有 N-1 个根(计重数)。矛盾。故 $P \equiv 0$。这证明齐次问题只有零解,从而线性方程组的系数矩阵非奇异,原问题存在唯一解。\blacksquare

特例:当所有 m_i = 0 时,$N = n+1$Hermite 插值退化为 Lagrange 插值;当 n+1 个节点每个都匹配函数值与一阶导数($m_i = 1$)时,$N = 2(n+1) = 2n+2$,称为标准 Hermite 插值,其多项式次数 $\le 2n+1$。


三、两点三次 Hermite 插值(重点)

这是工程与图形学中最常用的 Hermite 插值形式,必须重点掌握。

3.1 问题设定

取两个节点 $x_0, x_1$,每个节点匹配函数值与一阶导数:


H(x_0) = f(x_0),\quad H'(x_0) = f'(x_0),\quad H(x_1) = f(x_1),\quad H'(x_1) = f'(x_1).

N = 4 个条件,故 H(x) 是唯一的次数 \le 3 的多项式(三次多项式)。

3.2 标准区间 [0,1] 上的四个基函数

为简化推导,先把区间映射到 $[0,1]$。令


t = \frac{x - x_0}{x_1 - x_0} \in [0, 1], \qquad h = x_1 - x_0.

我们寻找一组三次基函数 $H_{00}(t), H_{10}(t), H_{01}(t), H_{11}(t)$,使得


H(t) = H_{00}(t)\, p_0 + H_{10}(t)\, m_0 + H_{01}(t)\, p_1 + H_{11}(t)\, m_1,

其中 $p_0 = f(x_0)$p_1 = f(x_1) 是端点值,$m_0 = h f'(x_0)$m_1 = h f'(x_1) 是按区间长度缩放后的端点导数(因为对 t 求导带来因子 $h$,详见 3.4 节)。

每个基函数在 t=0,1 两端的"值/导数"特征如下表(这正是它们的定义性质):

基函数 值(0) 导数(0) 值(1) 导数(1) 作用
H_{00} 1 0 0 0 携带左端点值 p_0
H_{10} 0 1 0 0 携带左端点切线 m_0
H_{01} 0 0 1 0 携带右端点值 p_1
H_{11} 0 0 0 1 携带右端点切线 m_1

3.3 基函数的推导

每个基函数是 t 的三次多项式,写作 $H(t) = a t^3 + b t^2 + c t + d$,由上表的 4 个条件唯一确定。注意 $H'(t) = 3a t^2 + 2b t + c$。

推导 $H_{00}$:要求 $H_{00}(0)=1, H_{00}'(0)=0, H_{00}(1)=0, H_{00}'(1)=0$。

  • $H_{00}(0)=d=1$。
  • $H_{00}'(0)=c=0$。
  • $H_{00}(1)=a+b+c+d=a+b+1=0 \Rightarrow a+b=-1$。
  • $H_{00}'(1)=3a+2b+c=3a+2b=0 \Rightarrow b=-\tfrac{3}{2}a$。
  • 代入 $a+b=-1$$a-\tfrac{3}{2}a=-1 \Rightarrow -\tfrac{1}{2}a=-1 \Rightarrow a=2$,于是 $b=-3$。

\boxed{H_{00}(t) = 2t^3 - 3t^2 + 1.}

推导 $H_{10}$:要求 $H_{10}(0)=0, H_{10}'(0)=1, H_{10}(1)=0, H_{10}'(1)=0$。

  • $d=0$$c=1$。
  • $a+b+c+d=a+b+1=0 \Rightarrow a+b=-1$。
  • $3a+2b+c=3a+2b+1=0 \Rightarrow 3a+2b=-1$。
  • a+b=-1 得 $b=-1-a$,代入:$3a+2(-1-a)=-1 \Rightarrow a-2=-1 \Rightarrow a=1$$b=-2$。

\boxed{H_{10}(t) = t^3 - 2t^2 + t.}

推导 $H_{01}$:要求 $H_{01}(0)=0, H_{01}'(0)=0, H_{01}(1)=1, H_{01}'(1)=0$。

  • $d=0$$c=0$。
  • $a+b=1$$3a+2b=0 \Rightarrow b=-\tfrac{3}{2}a$。
  • $a-\tfrac{3}{2}a=1 \Rightarrow -\tfrac12 a=1 \Rightarrow a=-2$$b=3$。

\boxed{H_{01}(t) = -2t^3 + 3t^2.}

推导 $H_{11}$:要求 $H_{11}(0)=0, H_{11}'(0)=0, H_{11}(1)=0, H_{11}'(1)=1$。

  • $d=0$$c=0$。
  • $a+b=0$$3a+2b=1$。
  • 由 $b=-a$$3a-2a=1 \Rightarrow a=1$$b=-1$。

\boxed{H_{11}(t) = t^3 - t^2.}

验证(单位分解性质):注意 $H_{00}(t) + H_{01}(t) = (2t^3-3t^2+1) + (-2t^3+3t^2) = 1$。这保证了对常值函数 $f\equiv c$(其导数为 $0$)的插值结果恒为 $c$,符合预期。

3.4 完整公式(一般区间 $[x_0, x_1]$

t = (x-x_0)/h 代回,并注意链式法则 $\frac{\mathrm d}{\mathrm dx} = \frac{1}{h}\frac{\mathrm d}{\mathrm dt}$,对 x 的导数与对 t 的导数相差因子 $1/h$。因此端点导数 f'(x_i) 与对 t 的导数关系为 $\frac{\mathrm dH}{\mathrm dt}\big|_{t=0} = h f'(x_0)$,这解释了 3.2 节中为何令 $m_0 = h f'(x_0)$、$m_1 = h f'(x_1)$。最终插值多项式为


\boxed{
H(x) = H_{00}(t)\,f(x_0) + H_{10}(t)\,h\,f'(x_0) + H_{01}(t)\,f(x_1) + H_{11}(t)\,h\,f'(x_1),
\qquad t=\frac{x-x_0}{h},\ h=x_1-x_0.
}

展开为


\begin{aligned}
H(x) ={}& (2t^3-3t^2+1)\,f(x_0) + (t^3-2t^2+t)\,h\,f'(x_0) \\
&+ (-2t^3+3t^2)\,f(x_1) + (t^3-t^2)\,h\,f'(x_1).
\end{aligned}

3.5 数值算例

设 $f(x) = \sin x$,节点 $x_0 = 0$$x_1 = \tfrac{\pi}{2}$。则


\begin{aligned}
&f(x_0) = \sin 0 = 0, & &f'(x_0) = \cos 0 = 1, \\
&f(x_1) = \sin\tfrac{\pi}{2} = 1, & &f'(x_1) = \cos\tfrac{\pi}{2} = 0,
\end{aligned}

且 $h = \tfrac{\pi}{2} \approx 1.5708$。代入完整公式(仅 $f(x_0)=0$、f'(x_1)=0 两项消失):


H(x) = H_{10}(t)\,h\cdot 1 + H_{01}(t)\cdot 1
= h(t^3 - 2t^2 + t) + (-2t^3 + 3t^2),

其中 $t = x / h = \dfrac{2x}{\pi}$。

在区间中点 x = \tfrac{\pi}{4} 处检验(此时 $t = 0.5$):


\begin{aligned}
H_{10}(0.5) &= 0.125 - 0.5 + 0.5 = 0.125, \\
H_{01}(0.5) &= -0.25 + 0.75 = 0.5, \\
H(\tfrac{\pi}{4}) &= 1.5708 \times 0.125 + 1 \times 0.5 = 0.19635 + 0.5 = 0.69635.
\end{aligned}

真实值 $\sin\tfrac{\pi}{4} = \tfrac{\sqrt2}{2} \approx 0.70711$。误差约为 $0.0108$,对仅用两个节点的三次插值而言已相当精确。作为对比,仅用相同两节点的线性 Lagrange 插值在中点给出 $0.5$,误差高达 $0.207$,可见匹配导数信息带来的显著改进。


四、一般 Hermite 插值的构造方法

4.1 方法一:基函数法(广义 Lagrange 基)

标准 Hermite 插值(每个节点匹配 f(x_i) 与 $f'(x_i)$$i=0,\dots,n$),插值多项式次数 $\le 2n+1$,可写成


H_{2n+1}(x) = \sum_{i=0}^{n} f(x_i)\, h_i(x) + \sum_{i=0}^{n} f'(x_i)\, \hat h_i(x),

其中 h_i(x)\hat h_i(x) 是满足下列"选择性"条件的基函数(\delta_{ij} 为 Kronecker 符号):


\begin{aligned}
h_i(x_j) = \delta_{ij}, &\qquad h_i'(x_j) = 0, \\
\hat h_i(x_j) = 0, &\qquad \hat h_i'(x_j) = \delta_{ij}.
\end{aligned}

构造公式:借助 Lagrange 基函数


\ell_i(x) = \prod_{\substack{j=0 \\ j\ne i}}^{n} \frac{x - x_j}{x_i - x_j},

可以证明


\boxed{
\begin{aligned}
h_i(x) &= \big[\,1 - 2(x - x_i)\,\ell_i'(x_i)\,\big]\,\ell_i^2(x), \\
\hat h_i(x) &= (x - x_i)\,\ell_i^2(x).
\end{aligned}
}

验证思路:因 $\ell_i(x_j) = \delta_{ij}$,故 $\ell_i^2(x_j) = \delta_{ij}$,于是 \hat h_i(x_j) = (x_j-x_i)\delta_{ij} = 0 对一切 j 成立;又 $\hat h_i'(x) = \ell_i^2(x) + (x-x_i)\cdot 2\ell_i\ell_i'$,在 x=x_j 处当 j\ne i\ell_i(x_j)=0 使两项皆为 $0$,当 j=i 时第一项 $\ell_i^2(x_i)=1$、第二项含因子 $(x_i-x_i)=0$,故 $\hat h_i'(x_j)=\delta_{ij}$。h_i 中的线性因子 [1 - 2(x-x_i)\ell_i'(x_i)] 正是为抵消 \ell_i^2x_i 处的导数而精心设计的。

基函数法概念清晰、利于理论分析,但当节点数较多或含高阶切触时,公式变得繁琐,实际计算更推荐下面的差商法

4.2 方法二:重节点的差商法(Newton 形式,推荐)

Newton 均差(divided differences,差商)插值可以自然地推广到 Hermite 情形:把每个节点按其重数 m_i+1 重复列出,对于重复的节点,差商表中无法用普通差商公式(会出现 $0/0$)的位置,用导数值填充

4.2.1 重节点差商的定义

普通差商递归定义为


f[x_i] = f(x_i), \qquad
f[x_i, \dots, x_{i+k}] = \frac{f[x_{i+1},\dots,x_{i+k}] - f[x_i,\dots,x_{i+k-1}]}{x_{i+k} - x_i}.

当节点重合($x_{i+k} \to x_i$)时,分母为零。此时由微分中值定理的极限给出重节点差商


\boxed{\,\underbrace{f[x_i, x_i, \dots, x_i]}_{k+1 \text{ 个}} = \frac{f^{(k)}(x_i)}{k!}.\,}

特别地:


f[x_i, x_i] = f'(x_i), \qquad f[x_i, x_i, x_i] = \frac{f''(x_i)}{2}.

4.2.2 构造步骤

  1. 建立重复节点序列 $z_0, z_1, \dots, z_{N-1}$:把 x_i 重复 m_i+1 次依次排列。
  2. 建立差商表。**对角线(最高阶差商)**逐列计算:
    • 若相邻两个 z 不相等,用普通差商公式;
    • 若相邻两个 z 相等(对应同一节点),用上面的导数公式填充。
  3. 表的顶部对角线元素作为 Newton 系数,写出多项式:

\boxed{
H(x) = \sum_{k=0}^{N-1} f[z_0, z_1, \dots, z_k] \prod_{j=0}^{k-1}(x - z_j).
}

4.2.3 算例:带重节点的差商表

求满足下列条件的多项式(即两点三次 Hermite,与第三节呼应,便于互相验证):


f(0) = 1,\quad f'(0) = 0,\quad f(1) = 0,\quad f'(1) = -1.

重复节点序列:$z_0 = z_1 = 0$$z_2 = z_3 = 1$。差商表如下(左列为 z 与 $f$,向右逐阶):


\begin{array}{c|cccc}
z & f[\cdot] & f[\cdot,\cdot] & f[\cdot,\cdot,\cdot] & f[\cdot,\cdot,\cdot,\cdot] \\ \hline
0 & 1 & & & \\
  &   & \mathbf{0} & & \\
0 & 1 & & -1 & \\
  &   & -1 & & \mathbf{1} \\
1 & 0 & & 0 & \\
  &   & -1 & & \\
1 & 0 & & & \\
\end{array}

逐项说明:

  • 一阶差商列:
    • $f[z_0,z_1] = f[0,0] = f'(0) = 0$(重节点,用导数)。
    • $f[z_1,z_2] = f[0,1] = \dfrac{0 - 1}{1 - 0} = -1$(普通差商)。
    • $f[z_2,z_3] = f[1,1] = f'(1) = -1$(重节点,用导数)。
  • 二阶差商列:
    • $f[z_0,z_1,z_2] = \dfrac{f[z_1,z_2] - f[z_0,z_1]}{z_2 - z_0} = \dfrac{-1 - 0}{1 - 0} = -1$。
    • $f[z_1,z_2,z_3] = \dfrac{f[z_2,z_3] - f[z_1,z_2]}{z_3 - z_1} = \dfrac{-1 - (-1)}{1 - 0} = 0$。
  • 三阶差商(顶部):
    • $f[z_0,z_1,z_2,z_3] = \dfrac{f[z_1,z_2,z_3] - f[z_0,z_1,z_2]}{z_3 - z_0} = \dfrac{0 - (-1)}{1 - 0} = 1$。

于是顶部对角线系数依次为 $1,\ 0,\ -1,\ 1$Newton 形式为


\begin{aligned}
H(x) &= 1 + 0\cdot(x-0) + (-1)(x-0)(x-0) + 1\cdot(x-0)(x-0)(x-1) \\
&= 1 - x^2 + x^2(x-1) \\
&= 1 - x^2 + x^3 - x^2 \\
&= x^3 - 2x^2 + 1.
\end{aligned}

验证H(0)=1 ✓;$H'(x)=3x^2-4x$H'(0)=0 ✓;H(1)=1-2+1=0 ✓;H'(1)=3-4=-1 ✓。四个切触条件全部满足,构造正确。

说明:差商法的最大优点是统一处理任意阶切触。无论某节点要匹配到几阶导数,只需把它重复相应次数、在重节点位置填入 f^{(k)}(x_i)/k! 即可,无需为每种情形单独设计基函数。这也是教科书和数值库内部最常采用的实现思路。


五、误差分析

5.1 误差余项公式

定理(Hermite 插值余项) 设 $f \in C^{N}[a,b]$,节点 x_0,\dots,x_n \in [a,b] 互异,切触阶为 $m_0,\dots,m_n$$N=\sum(m_i+1)$H(x) 为满足全部切触条件、次数 \le N-1 的 Hermite 插值多项式。则对任意 $x\in[a,b]$,存在依赖于 x 的 $\xi=\xi(x)\in(a,b)$,使得


\boxed{\,f(x) - H(x) = \frac{f^{(N)}(\xi)}{N!}\,\prod_{i=0}^{n}(x - x_i)^{m_i+1}.\,}

证明要点(Rolle 定理法):固定 $x\ne x_i$。令节点因子 $W(t)=\prod_i (t-x_i)^{m_i+1}$(次数为 $N$),并构造辅助函数


g(t) = f(t) - H(t) - \frac{f(x)-H(x)}{W(x)}\,W(t).

gt=x 处为零,且在每个 x_i 处有 m_i+1 重零点(因 f-HWx_i 处都有相应阶的零)。于是 $g$(计重数)至少有 N+1 个零点。反复使用 Rolle 定理,g^{(N)} 至少有一个零点 $\xi$。由于 H 次数 \le N-1 故 $H^{(N)}\equiv 0$,而 $W^{(N)}=N!$,代入 g^{(N)}(\xi)=0 解得


f^{(N)}(\xi) - \frac{f(x)-H(x)}{W(x)}\,N! = 0
\;\Longrightarrow\;
f(x)-H(x) = \frac{f^{(N)}(\xi)}{N!}W(x). \qquad\blacksquare

5.2 标准 Hermite(每点匹配值与一阶导)的余项

此时每个 $m_i=1$$N=2n+2$,余项为


f(x) - H(x) = \frac{f^{(2n+2)}(\xi)}{(2n+2)!}\prod_{i=0}^{n}(x-x_i)^2.

两点三次情形$n=1$$N=4$):


f(x) - H_3(x) = \frac{f^{(4)}(\xi)}{4!}(x-x_0)^2(x-x_1)^2 = \frac{f^{(4)}(\xi)}{24}(x-x_0)^2(x-x_1)^2.

注意节点因子 (x-x_i)^2 \ge 0 恒非负,这与 Lagrange 情形(节点因子可正可负)不同,反映了"相切"带来的更强约束。

5.3 与 Lagrange 插值误差的对比

对比项 Lagrange 插值(n+1 点) Hermite 插值(标准,n+1 点)
多项式次数 \le n \le 2n+1
余项导数阶 f^{(n+1)} f^{(2n+2)}
余项公式 \dfrac{f^{(n+1)}(\xi)}{(n+1)!}\prod (x-x_i) \dfrac{f^{(2n+2)}(\xi)}{(2n+2)!}\prod (x-x_i)^2
节点因子符号 可正可负 \ge 0
收敛阶(等距 $h$ O(h^{n+1}) O(h^{2n+2})

关键结论:在使用相同节点数的前提下,Hermite 插值由于额外利用了导数信息,余项中出现更高阶的导数更高次的节点因子幂,因而通常具有更高的逼近精度(更高的收敛阶)。代价是需要已知导数值,且多项式次数翻倍——次数过高时同样可能出现 Runge 现象,故实际更常用分段形式(见第六节)。


六、与样条的联系

6.1 分段三次 Hermite 插值

当节点很多时,直接构造高次 Hermite 多项式会引发振荡(Runge 现象)。实用做法是分段:在每个相邻区间 [x_i, x_{i+1}] 上用第三节的两点三次 Hermite 公式构造一段三次多项式,再拼接起来。

由于每段都在端点匹配函数值与一阶导数,拼接处天然满足


H(x_i^-) = H(x_i^+) = f(x_i), \qquad H'(x_i^-) = H'(x_i^+) = f'(x_i),

即整条曲线达到 C^1 连续(函数与一阶导都连续)。这正是分段三次 Hermite 插值(Piecewise Cubic Hermite Interpolation)。其前提是每个节点的导数 f'(x_i) 已知或被估计出来

6.2 三次样条与 Hermite 形式的关系

**三次样条(cubic spline**同样是分段三次、C^1 连续,但它额外要求


H''(x_i^-) = H''(x_i^+), \qquad i=1,\dots,n-1,

二阶导数也连续,从而整体达到 C^2 连续,曲线更光滑(曲率不突变)。

两者的本质区别在于"导数从何而来":

  • 分段 Hermite:各节点的斜率 f'(x_i)给定或局部估计的(局部方法,每段相互独立),只保证 $C^1$。
  • 三次样条:斜率(或二阶导)是通过求解一个全局三对角线性方程组确定的,目的是让二阶导连续,因此是全局方法,达到 $C^2$,但任一数据点的改动会影响整条曲线。

事实上,任何三次样条都可以改写成分段 Hermite 形式:只要先解出样条在各节点的导数值 $s'(x_i)$,再把这些导数当作 Hermite 的输入即可。所以"三次样条"可视为"用全局光滑性条件自动确定斜率的分段三次 Hermite 插值"。

6.3 单调性保持(PCHIP

分段三次 Hermite 的一个重要变体是 PCHIPPiecewise Cubic Hermite Interpolating Polynomial。它不直接使用真实导数,而是用一套特殊规则估计每个节点的斜率 $d_i$,使得:

  • 在数据单调的区间内,插值曲线保持单调,不产生过冲(overshoot)/ 振荡;
  • 在局部极值点处令斜率为 $0$,避免越过数据点。

具体地,PCHIP 在内部节点用相邻区间斜率的加权调和平均来估计 $d_i$:若相邻两段割线斜率 \delta_{i-1}, \delta_i 同号,则


\frac{w_1+w_2}{d_i} = \frac{w_1}{\delta_{i-1}} + \frac{w_2}{\delta_i},
\qquad w_1 = 2h_i + h_{i-1},\ w_2 = h_i + 2h_{i-1},

否则(异号或某段为零,即遇到局部极值)令 $d_i = 0$。这保证了形状保持性。与三次样条相比,PCHIP 牺牲了 C^2 光滑(只保 $C^1$),换来无过冲的视觉与物理可靠性,非常适合插值带有尖锐变化或单调段的数据。


七、应用场景

7.1 计算机图形学:三次 Hermite 曲线

第三节的四基函数 H_{00},H_{10},H_{01},H_{11} 正是图形学中**三次 Hermite 曲线(Cubic Hermite Spline**的数学基础。给定两端点 \mathbf P_0,\mathbf P_1 与两端切向量 $\mathbf T_0,\mathbf T_1$(这里把标量推广为向量,对每个坐标分量分别插值):


\mathbf P(t) = H_{00}(t)\mathbf P_0 + H_{10}(t)\mathbf T_0 + H_{01}(t)\mathbf P_1 + H_{11}(t)\mathbf T_1,\quad t\in[0,1].

设计师通过拖动切向量即可直观地控制曲线的"出入方向"。

Catmull-Rom 样条是其著名特例:它自动地把每个控制点的切向量取为相邻两点连线方向


\mathbf T_i = \frac{1}{2}(\mathbf P_{i+1} - \mathbf P_{i-1}),

从而只需给一串点就能生成一条经过所有控制点、C^1 连续的光滑曲线,广泛用于路径与曲线设计。

7.2 动画关键帧插值与相机路径

在动画中,美术师设置若干关键帧(keyframe:在某些时刻指定物体的位置、旋转、缩放等属性。系统需要在关键帧之间"补间(in-between"。使用 Hermite 插值(指定每个关键帧的属性值及其变化速率/切线)可以让运动平滑、避免在关键帧处出现速度突变(折角)。相机沿预定轨迹平移、推拉时同样依赖 Hermite/样条曲线得到流畅运镜。

7.3 数值微分方程与轨迹规划

  • 常微分方程数值解:一些方法(如 HermiteObreschkoff、含导数信息的密集输出/dense output)利用解在网格点的函数值与导数值(导数恰由 ODE 右端 f(t,y) 直接给出)做 Hermite 插值,得到任意时刻的高精度连续解。
  • 机器人/无人机轨迹规划:要求轨迹在路点(waypoint)处同时满足位置与速度(甚至加速度)约束,正是高阶 Hermite 插值的典型用武之地——它能保证速度连续,使运动平稳、可执行。

八、Python 代码示例

下面用 numpy 从零实现两点三次 Hermite 插值,并用 SciPy 的 CubicHermiteSplineBPoly.from_derivatives 进行对照验证。代码可直接运行。

import numpy as np

# ----------------------------------------------------------------------
# 1) 基函数法:标准区间 [0,1] 上的四个三次 Hermite 基函数
# ----------------------------------------------------------------------
def hermite_basis(t):
    """返回 (H00, H10, H01, H11) 在参数 t 处的值。t 可为标量或 numpy 数组。"""
    H00 = 2 * t**3 - 3 * t**2 + 1     # 携带左端点值
    H10 = t**3 - 2 * t**2 + t         # 携带左端点切线
    H01 = -2 * t**3 + 3 * t**2        # 携带右端点值
    H11 = t**3 - t**2                 # 携带右端点切线
    return H00, H10, H01, H11


def cubic_hermite(x, x0, x1, p0, p1, m0, m1):
    """
    两点三次 Hermite 插值。
    x0, x1 : 两个节点
    p0, p1 : 端点函数值 f(x0), f(x1)
    m0, m1 : 端点一阶导数 f'(x0), f'(x1)
    返回 H(x)。
    """
    h = x1 - x0
    t = (x - x0) / h
    H00, H10, H01, H11 = hermite_basis(t)
    # 注意导数项需乘以区间长度 h(链式法则)
    return H00 * p0 + H10 * (h * m0) + H01 * p1 + H11 * (h * m1)


# ----------------------------------------------------------------------
# 2) 算例:用 f(x)=sin(x) 在 [0, pi/2] 上做两点三次 Hermite 插值
# ----------------------------------------------------------------------
x0, x1 = 0.0, np.pi / 2
p0, p1 = np.sin(x0), np.sin(x1)      # 函数值: 0, 1
m0, m1 = np.cos(x0), np.cos(x1)      # 导数值: 1, 0

xs = np.linspace(x0, x1, 9)
H_vals = cubic_hermite(xs, x0, x1, p0, p1, m0, m1)
true_vals = np.sin(xs)

print("x        Hermite      sin(x)       误差")
for x, h, s in zip(xs, H_vals, true_vals):
    print(f"{x:.4f}   {h:.6f}   {s:.6f}   {abs(h - s):.2e}")

# 在中点 pi/4 处单独检验(对应正文 3.5 节)
xm = np.pi / 4
print(f"\n中点 H(pi/4) = {cubic_hermite(xm, x0, x1, p0, p1, m0, m1):.5f}, "
      f"真值 = {np.sin(xm):.5f}")

# ----------------------------------------------------------------------
# 3) 与 SciPy 对照(若已安装 scipy
# ----------------------------------------------------------------------
try:
    from scipy.interpolate import CubicHermiteSpline, BPoly

    # CubicHermiteSpline 直接接受节点、函数值、导数值
    nodes = np.array([x0, x1])
    vals  = np.array([p0, p1])
    ders  = np.array([m0, m1])
    chs = CubicHermiteSpline(nodes, vals, ders)

    # BPoly.from_derivatives: 每个节点给 [值, 一阶导]
    bp = BPoly.from_derivatives(nodes, [[p0, m0], [p1, m1]])

    max_err_chs = np.max(np.abs(chs(xs) - H_vals))
    max_err_bp  = np.max(np.abs(bp(xs)  - H_vals))
    print(f"\n与 CubicHermiteSpline 的最大偏差: {max_err_chs:.2e}")
    print(f"与 BPoly.from_derivatives 的最大偏差: {max_err_bp:.2e}")
    # 两者应与自实现完全一致(偏差约为机器精度 ~1e-16)
except ImportError:
    print("\n未安装 scipy,跳过对照验证。")

预期输出(节选):自实现结果与 SciPy 两种方法的偏差均在机器精度量级(约 $10^{-16}$),中点处 $H(\pi/4)\approx 0.69635$,与正文 3.5 节手算一致。


九、小结表格

下表对比三种最常用的插值方案,帮助快速选型:

对比维度 Lagrange 插值 Hermite 插值(标准) 三次样条(cubic spline
匹配条件 仅节点函数值 f(x_i) 节点函数值 f(x_i) 与导数值 $f'(x_i)$(可含更高阶) 节点函数值;导数由全局光滑条件自动确定
多项式形态 单个次数 \le n 的多项式 单个次数 \le 2n+1 的多项式(或分段三次) 分段三次多项式
连续性 自身光滑(单个多项式),分段拼接仅 C^0 节点处达 $C^1$(分段时);插值更"贴合" $C^2$(二阶导连续,最光滑)
是否需导数 (须已知或估计 $f'$ 否(自动求解)
误差余项 \dfrac{f^{(n+1)}(\xi)}{(n+1)!}\prod(x-x_i) \dfrac{f^{(2n+2)}(\xi)}{(2n+2)!}\prod(x-x_i)^2 分段,O(h^4) 量级
局部/全局 全局(改一点影响整体) 局部(分段 Hermite 每段独立) 全局(解三对角方程组)
典型用途 理论分析、低阶插值、推导数值公式 图形学曲线、动画关键帧、轨迹规划、ODE 密集输出 数据光滑拟合、CAD 曲线、平滑插值
代表实现 CubicHermiteSplineBPoly.from_derivatives、PCHIP CubicSpline

参考与延伸

  • 经典数值分析教材(如 Burden & Faires《Numerical Analysis》、李庆扬《数值分析》)中关于 Hermite 插值与差商的章节。
  • SciPy 文档:CubicHermiteSplinePchipInterpolatorBPoly.from_derivatives
  • 计算机图形学中关于 Hermite 曲线、Bézier 曲线与 Catmull-Rom 样条相互转化的资料。

一句话总结:Hermite 插值通过同时匹配函数值与导数值,让插值曲线在节点处"相切",以更高的收敛阶和更好的光滑性逼近原函数;其两点三次形式与分段推广(含 PCHIP、Catmull-Rom)是图形学、动画与轨迹规划的基石,实际构造首选重节点差商法