跳到主要内容

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

参考文献

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_ixx 轴上的投影 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),jipi(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)=aji(xxj)f_i(x)=a\cdot\prod_{j\not=i}(x-x_j),将点 pi(xi,yi)p_i(x_i,y_i) 代入可以知道,a=yiji(xixj)a=\frac{y_i}{\prod_{j\not=i}(x_i-x_j)},所以

fi(x)=yiji(xxj)ji(xixj)=yiji(xxj)(xixj)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=1nyiji(xxj)(xixj)f_(x)=\sum_{i=1}^ny_i\cdot\prod_{j\not=i}\frac{(x-x_j)}{(x_i-x_j)}

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

多项式快速插值

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

ji(xixj)=limxxij=1n(xxj)xxi=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)ji(xxj)f(x)=\sum_{i=1}^n\frac{y_i}{M'(x_i)}\prod_{j\not=i}(x-x_j)

首先通过分治计算出 M(x)M(x) 的系数表示,接着可以通过多点求值在 O(nlog2n)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)=xx1f(x)=v_1,M(x)=x-x_1

否则令:

f0(x)=i=1n2vijin2<jn(xxj)M0(x)=i=1n2(xxi)f1(x)=i=n2+1nvijin2<jn(xxj)M1(x)=i=n2+1n(xxi)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(nlogn)O(n\log n)