拉格朗日插值

拉格朗日插值

普通拉格朗日插值

众所周知,n+1 个横坐标互不相同的点可以确定出唯一的最高次为 n 的多项式。当给定你 n 个点并要求你求出横坐标为 x 的点的纵坐标,高斯消元虽是个选择,但是 O(n3) 的时间复杂度显然不优。于是我们选择用 O(n2) 的拉格朗日插值解决这类问题。

我们先来考虑构造一个函数 L(x),我们希望这个函数在 x=xi 时等于 1,在 x=xj(0jn,ji) 时等于 0

我们想达到这个目的,不难想到去令多个式子相乘,这样的话只要有一项等于 0,则总的式子就等于 0

所以我们先设 L(x)=0jn(xxj),但是我们发现当 x=xi 时也等于 0

所以我们再设 L(x)=0jnij(xxj),但是我们发现当 x=xi 时不等于 1

所以我们设 L(x)=0jnijxxjxixj

然后就得到了一个非常巧的函数。

然后就有:

f(x)=i=0nyiL(x)=i=0nyijixxjxixj

这个式子显然是可以在 O(n2) 的时间复杂度内算出来的。

在横坐标连续的情况下的拉格朗日插值

当横坐标连续时,我们可以将 xi 看作 ixj 看作 j,所以原式变成:

f(x)=i=0nyijixjij

现在的重点在于如何快速算出 jixjij

我们发现分子可以写成前缀积和后缀积相乘的形式,所以设 prei=j=0i(xj),sufi=j=in(xj),然后分子就可以写成 prei1×sufi+1

但是我们发现,分子好像也可以不写成前缀积和后缀积相乘的形式。我们直接预处理出 prod=j=0n(xj),然后分子就是 prodxi,我们把 xi 移到分母上即可。

我们发现分母可以写成阶乘的形式,所以设 facii 的阶乘,然后分母就可以写成 faci1×facni

但是我们发现,当 i<j 时有可能会使原式变为负数。我们考虑什么时候会出现这种情况。

对于 m 个负数相乘,当 m 为偶数时结果为正,m 为奇数时结果为负。对于一个 i,大于 ij 的个数为 ni,所以我们让分母再乘上 (1)ni 即可。

所以整合一下:

f(x)=i=0nyi×prei1×sufi+1(1)ni×faci1×facni=i=0nyi×prod(xi)×(1)ni×faci1×facni

我们发现这个式子是 O(n) 的。

重心拉格朗日插值

如果我们需要计算多次拉格朗日插值,那每一次都跑一边 O(n2) 这个过程是很不优的,因为我们重复算了很多东西。

所以我们考虑重写一下原式。

f(x)=i=0nyijixxjxixj=i=0nyiji(xxj)pi1xixp=i=0nji(xxj)yipi(xixp)=j=0n(xxj)i=0nyipi(xixp)×1xxi

然后我们设 prodi=yipi(xixp),gx=j=0n(xxj)

所以有:

f(x)=g(x)i=0nprodixxi

O(n2) 预处理出 prod 后,这个式子可以 O(n) 计算。

posted @   流星Meteor  阅读(61)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示