跳到主要内容

学习笔记:拉格朗日插值法

参考文献​

oi-wiki 插值

oi-wiki 多项式快速插值

前置知识​

多项式基础

洛必达法则

引入​

当我们面临一个问题:

有 nn 个点 (x1,y1),(x2,y2),⋯ ,(xn,yn)(x_1,y_1),(x_2,y_2),\cdots,(x_n,y_n),求一个经过所有点的函数 f(x)f(x) 的函数表达式。

我们可以通过一定的拟合方式找出这个函数。

比如用分段线性函数拟合 f(x)f(x),这种方法被称作线性插值。

又或者用多项式拟合 f(x)f(x),这种方法被称作多项式插值。

多项式插值的其中一种方式就是拉格朗日插值法

Lagrange 插值法​

首先设第 ii 个点 pip_i 在 xx 轴上的投影 pi′=(xi,0)p_i'=(x_i,0)。

考虑构造 nn 个函数 f1(x),f2(x),⋯ ,fn(x)f_1(x),f_2(x),\cdots,f_n(x),满足其图像经过 {pj′(xj,0),j≠ipi(xi,yi)\begin{cases} p_j'(x_j,0),j\not=i\\ p_i(x_i,y_i) \end{cases},则可以得到 f(x)=∑i=1nfi(x)\displaystyle f(x)=\sum_{i=1}^nf_i(x)。

可以设 fi(x)=a⋅∏j≠i(x−xj)f_i(x)=a\cdot\prod_{j\not=i}(x-x_j),将点 pi(xi,yi)p_i(x_i,y_i) 代入可以知道,a=yi∏j≠i(xi−xj)a=\frac{y_i}{\prod_{j\not=i}(x_i-x_j)},所以

fi(x)=yi⋅∏j≠i(x−xj)∏j≠i(xi−xj)=yi⋅∏j≠i(x−xj)(xi−xj)f_i(x)=y_i\cdot\frac{\prod_{j\not=i}(x-x_j)}{\prod_{j\not=i}(x_i-x_j)}=y_i\cdot\prod_{j\not=i}\frac{(x-x_j)}{(x_i-x_j)}

因此我们就可以得到拉格朗日插值法形如:

f(x)=∑i=1nyi⋅∏j≠i(x−xj)(xi−xj)f_(x)=\sum_{i=1}^ny_i\cdot\prod_{j\not=i}\frac{(x-x_j)}{(x_i-x_j)}

朴素实现的时间复杂度为 O(nlog⁡n)O(n\log n)。

多项式快速插值​

记多项式 M(x)=∏i=1n(x−xi)M(x)=\prod_{i=1}^n(x-x_i),由洛必达法则可知:

∏j≠i(xi−xj)=lim⁡x→xi∏j=1n(x−xj)x−xi=M′(xi)\prod_{j\not=i}(x_i-x_j)=\lim_{x\rightarrow x_i}\frac{\prod_{j=1}^n(x-x_j)}{x-x_i}=M'(x_i)

因此可以将多项式表示为

f(x)=∑i=1nyiM′(xi)∏j≠i(x−xj)f(x)=\sum_{i=1}^n\frac{y_i}{M'(x_i)}\prod_{j\not=i}(x-x_j)

首先通过分治计算出 M(x)M(x) 的系数表示,接着可以通过多点求值在 O(nlog⁡2n)O(n\log^2n) 时间内计算出所有的 M′(xi)M'(x_i)。

令 vi=yiM′(xi)v_i=\frac{y_i}{M'(x_i)},考虑计算 f(x)f(x),对于 n=1n=1 的情况,有 f(x)=v1,M(x)=x−x1f(x)=v_1,M(x)=x-x_1。

否则令:

f0(x)=∑i=1⌊n2⌋vi∏j≠i∧⌊n2⌋<j≤n(x−xj)M0(x)=∏i=1⌊n2⌋(x−xi)f1(x)=∑i=⌊n2⌋+1nvi∏j≠i∧⌊n2⌋<j≤n(x−xj)M1(x)=∏i=⌊n2⌋+1n(x−xi)f_0(x)=\sum_{i=1}^{\lfloor\frac n2\rfloor}v_i\prod_{j\not=i\land\lfloor\frac n2\rfloor<j\leq n}(x-x_j)\\ M_0(x)=\prod_{i=1}^{\lfloor\frac n2\rfloor}(x-x_i)\\ f_1(x)=\sum_{i=\lfloor\frac n2\rfloor+1}^nv_i\prod_{j\not=i\land\lfloor\frac n2\rfloor<j\leq n}(x-x_j)\\ M_1(x)=\prod_{i=\lfloor\frac n2\rfloor+1}^{n}(x-x_i)

可得 f(x)=f0(x)M1(x)+f1(x)M0(x),M(x)=M0(x)M1(x)f(x)=f_0(x)M_1(x)+f_1(x)M_0(x),M(x)=M_0(x)M_1(x),因此可以分治计算,复杂度 O(nlog⁡n)O(n\log n)。