样条插值是常用的插值方法,用至多三次的多项式对样本点进行插值,满足曲线连续可微。以二维空间为例,常见的插值问题是,给定点列
其中
, 寻找适当的连续可微函数
使得
. 例如最常用的三次样条插值, 是假设
在
上是三次多项式
, 其中
系数待定, 在此区间上需要满足
过两个样本点, 且在两个端点是连续可微的, 即
对于三次多项式而言有4个系数待定, 而这四个方程刚好确定了四个系数, 就可以得到插值函数.
但有时候会遇到诸
并不是严格单调递增的,例如这些有序点列在平面上转了一个圈,那么就不能直接用上面的方法, 毕竟最后得到的并不是一个"函数"了 (例如可能存在
). 那么这样如何得到一条光滑的曲线穿过这串有序点列呢? 其实也很容易. 引入 单调递增的序列
, 构造新的两串有序点列
对这两个点列分别进行样条插值, 分别得到连续可微的插值函数
. 构造映射
那么
是一条连续可微的曲线.
下面是用Python实现的实例
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = [4,4]
import scipy.interpolate as spi
x = [np.cos(k) for k in np.arange(0,2*np.pi, 2*np.pi / 8)]
y = [np.sin(k) for k in np.arange(0,2*np.pi, 2*np.pi / 8)]
w = [k for k in np.arange(0,2*np.pi, 2*np.pi / 8)]
X = spi.splrep(w, x, k = 3)
Y = spi.splrep(w, y, k = 3)
W = [k for k in np.arange(0,2*np.pi - 2*np.pi / 8, 1e-4)]
plt.plot(spi.splev(W,X), spi.splev(W,Y), label = 'Interpolation', c = 'black');
plt.scatter(x,y,label = 'Inital point', c = 'C0');
plt.legend()
plt.show()