【学习笔记】拉格朗日插值

其实好久之前就学过了, 但是好像有些操作并不是很清楚, 那就给它记录一下吧.


拉格朗日插值法

众所周知, $n+1$ 个点可以确定 $n$ 次多项式(貌似所有博客都是这句话开的头).

求这个多项式无脑的办法是高斯消元, 时间复杂度 $\mathcal{O}(n^3)$ , 拉格朗日插值则可以做到 $\mathcal{O}(n^2)$ .

假设多项式为 $f(x)$ , 第 $i$ 个点的坐标为 $(x_i,y_i)$ , 我们要求这个多项式在 $x$ 处的取值.

根据拉格朗日插值法,

直观好像不好理解, 但其实带入个值展开你就会发现, 如果我们带入了 $x_i$ 那么, 后面的连乘的值就会是 $1$ , 否则是 $0$ , 因此正确性得以保证.

接下来拓展一点东西.

在 $x$ 的取值连续时的做法

在 $x$ 的取值连续的时候式子可以改写成 $f(x) = \sum\limits_{i=0}^{n}{y_i}\prod\limits_{i \not= j}{\frac{x-j}{i-j}}$ .

考虑如何快速计算 $\prod\limits_{i \not= j}{\frac{x-j}{i-j}}$ .

对于分子来说, 维护关于 $x$ 的前缀积后缀积即可, 也就是 $pre_i = \prod\limits_{j=0}^{i}{x-j},suf_i = \prod\limits_{j=i}^{n}{x-j}$ .

对于分母来说就是阶乘的形式, 那么式子就变成了.

注意这可能会有符号问题, 当 $n-i$ 为奇数的时候, 分母应该取负号.

时间复杂度 $\mathcal{O}(n)$ .

重心拉格朗日插值法

再看看前面的式子,

设 $g=\prod\limits_{i=0}^{n}{x-x_i}$ ,

设 $h_i=\dfrac{y_i}{\prod\limits_{i\not=j}{x_i-x_j}}$ ,

这样每次新加入一个点的时候只需要新计算它的 $h_i$ 即可, 其实重心的定义是 $w_i = \dfrac{1}{\prod\limits_{i\not=j}{x_i-x_j}}$ .

对比原拉格朗日插值法的优势是, 对于一个新增的点, 拉格朗日插值需要 $\mathcal{O}(n^2)$ 的重新计算, 而重心拉格朗日插值法只需要将每一个 $h_i$ 除以 $x_{n+1}-x_j$ , 重新定义重心, 就可以在 $\mathcal{O}(n)$ 的时间复杂度内计算完成.

拉格朗日插值法插出系数

再接着看拉格朗日插值法的式子,

首先提出常数部分,

可以 $\mathcal{O}(n^2)$ 的求出每一个 $a_i$ .

然后求出一个多项式 $g(x) = \prod\limits_{i=0}^{n}{x-x_i}$ .

可以发现,

考虑如何快速求出后面的 $\dfrac{g(x)}{x-x_i}$ .

设 $h(x) = \dfrac{g(x)}{x-c}$ , 可以得到 $(x-c)h(x)=g(x)$ , 提取两边系数得到,

递推即可.

当然, 其实可以再无脑一点, 每次线性除以一个一次的多项式, 最后加和即可.