三次样条插值——三弯矩方法

         三次样条插值方法,是将一个曲线函数分成多段,每相邻的两个标准点就是一个三次多项式函数.也就是说,n+1个标准点,共有 n 个三次函数.求解分段时共有4*n个未知系数

S(x_{i})=a_{i}x^{3} + b_{i}x^{2} +c_{i}x+d_{i}

 其相邻的分段函数之间连续,一阶导连续,二阶导也连续。

因此 

  • 每个分段三次样条函数要经过每两个标准点即, S(x_{k}) =y_{k} 共可以列出2n 个方程;
  • 一阶导连续S'(x_{k-0}) =S'(x_{k+0})  共有n -1 个方程;
  • 二阶导连续S''(x_{k-0}) =S''(x_{k+0})  共有n -1 个方程,

共4n -2个方程,还要加上额外2个两两互不线性相关的方程才能求解得出 4n个未知系数。

这额外的2个方程就是所谓的边界条件。其分成左边界条件和右边界条件,分别用来进行模拟左外插和右外插。

主流边界条件如下

边界条件 说明 意义
Not-A-Knot
非扭结

左边界和右边界的三阶导数值相等

即 S'''(-\infty ) =S'''(1) , S'''(+\infty ) =S'''(n)

Natural 自然边界 指定端点二阶导数为0S''(-\infty ) =0, S''(+\infty ) =0
Clamped 固定边界 指定端点一阶导数

当然,也可以自行设置其他边界条件

利用三弯矩法求解三次样条方程

设三次样条函数 S(x) 和分段函数如下

        S(x)=S_{j}(x)

为表示方便,另

h_{j} =x_{j+1} -x_{j}

S''_{j}(x) = M_{j}

s_{j} =( y_{j+1} - y_{j} ) / h_{j}

这样 h 表示相邻的两个标准点的x轴距离, s表示斜率,M表示函数的二阶导

根据样条函数S(x)=S_{j}(x)的定义可知,其二阶导数必然是线性方程,且为连续的折现段。因此折现段上的任一点可由折现段两端的值以及该点的所处位置表示出来,即拉格朗日线性插值法:

S''(x) = \frac{ x_{j+1} - x}{ h_{j} } M_{j} + \frac{ x - x_{j}}{ h_{j} } M_{j+1}        .......①

对上式进行两次积分后得到

S(x) = \frac{ (x_{j+1} - x)^3}{ 6h_{j} } M_{j} + \frac{ (x - x_{j})^3}{ 6h_{j} } M_{j+1}+c_{1}x + c_{2}...........②

根据定义得知,函数必然经过标准点,因此把 S(x_{j})=y_{j},S(x_{j+1})=y_{j+1} 代入到上述公式中,得到公式

 S(x) = \frac{ (x_{j+1} - x)^3}{ 6h_{j} } M_{j} + \frac{ (x - x_{j})^3}{ 6h_{j} } M_{j+1}+\frac{y_{j} - \frac{M_{j}h_{j}^2}{6} }{h_{j}}(x_{j+1}-x) + \frac{y_{j+1} - \frac{M_{j+1}h_{j}^2}{6} }{h_{j}}(x-x_{j})...③                                                           

将 S(x)求导可得

S'(x) = -\frac{ (x_{j+1} - x)^2}{ 2h_{j} } M_{j} + \frac{ (x - x_{j})^2}{ 2h_{j} } M_{j+1}+\frac{y_{j+1}-y_{j}}{h_{j}}- (\frac{M_{j+1} -M_{j} }{6} h_{j})

S'(x) = -\frac{ (x_{j} - x)^2}{ 2h_{j-1} } M_{j-1} + \frac{ (x - x_{j-1})^2}{ 2h_{j-1} } M_{j}+\frac{y_{j}-y_{j-1}}{h_{j-1}}- (\frac{M_{j} -M_{j-1} }{6} h_{j-1})....④

S'(x-0) =S'(x+0)两式相等构成方程,

可通过移向得到方程组

\left\{\begin{matrix} \\ \mu_{1}M_{0} + \alpha_{1} M_{1} + \lambda_{1} M_{2} =d_{1} \\ \mu_{2}M_{1} + \alpha_{2} M_{2} + \lambda_{2} M_{3} =d_{2} \\ ... \\ \mu_{j}M_{j-1} + \alpha_{j} M_{j} + \lambda_{j} M_{j+1} =d_{j} \\ ... \\ \mu_{n-1}M_{n-2} + \alpha_{n-1} M_{n-1} + \lambda_{n-1} M_{n} =d_{n-1} \end{matrix}\right.

其中\mu _{j} = h_{j-1},\alpha_{j} = 2(h_{j-1}+h_{j}),\lambda _{j}=h_{j},d=6(s_{j}-s_{j-1})   .....................⑤

n-1个方程在加上两个边界方程,可以求解出 n+1 个M. 例如 "端点二阶导相等"的边界条件

\left\{\begin{matrix} M_{0}- M_{1}=0\\ \mu_{1}M_{0} + \alpha_{1} M_{1} + \lambda_{1} M_{2} =d_{1} \\ \mu_{2}M_{1} + \alpha_{2} M_{2} + \lambda_{2} M_{3} =d_{2} \\ ... \\ \mu_{j}M_{j-1} + \alpha_{j} M_{j} + \lambda_{j} M_{j+1} =d_{j} \\ ... \\ \mu_{n-1}M_{n-2} + \alpha_{n-1} M_{n-1} + \lambda_{n-1} M_{n} =d_{n-1} \\ M_{n-1} - M_{n} =0 \end{matrix}\right.

将左边界方程加入到方程组第0个方程位置,将右边界加入到方程组第n个方程位置,可以得到一个三对角方阵.

剩下的就是线性代数矩阵行变换求解出M,再代入S(x)函数③ 得到 S(x)的函数方程。

只要输入的标准点的x坐标两两不相等,其方程组就可以求解的出来。

你可能感兴趣的:(C++,算法,算法,三次样条,边界条件,矩阵,三弯矩)