拉格朗日插值法总结模板(1~n)
拉格朗日插值法
简介
在数值分析中,拉格朗日插值法是以法国十八世纪数学家约瑟夫·路易斯·拉格朗日命名的一种多项式插值方法。许多实际问题中都用函数来表示某种内在联系或规律,而不少函数都只能通过实验和观测来了解。如对实践中的某个物理量进行观测,在若干个不同的地方得到相应的观测值,拉格朗日插值法可以找到一个多项式,其恰好在各个观测的点取到观测到的值。这样的多项式称为拉格朗日(插值)多项式。
推导
假设现在我们得到了n+1n+1n+1 个点:(x0,y0),(x1,y1),…,(xn,yn)\left(x_{0}, y_{0}\right),\left(x_{1}, y_{1}\right), \ldots,\left(x_{n}, y_{n}\right)(x0,y0),(x1,y1),…,(xn,yn),需要求过这些点的nnn次多项式。
给出拉格朗日基本多项式:ℓi(x)=∏j=0,j!=inx−xjxi−xj\ell_{i}(x)=\prod_{j=0, j != i}^{n} \frac{x-x_{j}}{x_{i}-x_{j}} ℓi(x)=j=0,j!=i∏nxi−xjx−xj
可以看出这个基本多项式构造十分巧妙,它具有ℓi(xi)=1\ell_{i}\left(x_{i}\right)=1ℓi(xi)=1,并且ℓi(xj)=0,∀i!=j\ell_{i}\left(x_{j}\right)=0, \forall i !=jℓi(xj)=0,∀i!=j的性质。那么,接着构造出这个nnn次多项式:P(x)=∑i=0nyiℓi(x)P(x)=\sum_{i=0}^{n} y_{i} \ell_{i}(x) P(x)=i=0∑nyiℓi(x)
根据基本多项式的性质,我们可以知道P(xi)=yiP\left(x_{i}\right)=y_{i}P(xi)=yi,也就是经过了这n+1n+1n+1个点。通过简单的多项式乘法和多项式除法就可以在O(n2)O(n^2)O(n2)的时间求出这个多项式的系数表达。
举例:假设给出的三个点为(1,3)(2,7)(3,13)(1,3)(2,7)(3,13)(1,3)(2,7)(3,13),那么:
P(x)=3(x−2)(x−3)(1−2)(1−3)+7(x−1)(x−2)(2−1)(2−3)+13(x−1)(x−2)(3−1)(3−2)P(x)=3 \frac{(x-2)(x-3)}{(1-2)(1-3)}+7 \frac{(x-1)(x-2)}{(2-1)(2-3)}+13 \frac{(x-1)(x-2)}{(3-1)(3-2)}P(x)=3(1−2)(1−3)(x−2)(x−3)+7(2−1)(2−3)(x−1)(x−2)+13(3−1)(3−2)(x−1)(x−2)
当x连续时的优化
在绝大多数题目中我们需要用到的 xix_ixi 的取值都是连续的,这样的话我们可以把上面的算法优化到O(n)O(n)O(n)复杂度。
先给出上文推导出的拉格朗日差值公式:f(k)=∑i=0nyi∏i!=jk−x[j]x[i]−x[j]f(k)=\sum_{i=0}^{n} y_{i} \prod_{i != j} \frac{k-x[j]}{x[i]-x[j]} f(k)=i=0∑nyii!=j∏x[i]−x[j]k−x[j]
对于分子来说,我们维护出关于kkk的前缀积和后缀积,也就是:prei=∏j=0ik−j,sufi=∏j=ink−jp r e_{i}=\prod_{j=0}^{i} k-j , s u f_{i}=\prod_{j=i}^{n} k-j prei=j=0∏ik−j,sufi=j=i∏nk−j
对于分母来说,观察发现这其实就是阶乘的形式,我们用 fac[i]fac[i]fac[i] 表示 i!i!i!,
式子变为:f(k)=∑i=0nyiprei−1∗sufi+1fac[i]∗fac[N−i]f(k)=\sum_{i=0}^{n} y_{i} \frac{p r e_{i-1} * s u f_{i+1}}{f a c[i] * f a c[N-i]} f(k)=i=0∑nyifac[i]∗fac[N−i]prei−1∗sufi+1
注意:分母可能会出现符号问题,也就是说,当N−iN−iN−i为奇数时,分母应该取负号
重心拉格朗日插值法
再来看一下前面的式子f(k)=∑i=0nyi∏i!=jk−x[j]x[i]−x[j]f(k)=\sum_{i=0}^{n} y_{i} \prod_{i != j} \frac{k-x[j]}{x[i]-x[j]} f(k)=i=0∑nyii!=j∏x[i]−x[j]k−x[j]设g=∏i=1nk−x[i]g=\prod_{i=1}^{n} k-x[i]g=∏i=1nk−x[i],则:
f(k)=g∑i=0n∏i≠jyi(k−x[i])(x[i]−x[j])f(k)=g \sum_{i=0}^{n} \prod_{i \neq j} \frac{y_{i}}{(k-x[i])(x[i]-x[j])} f(k)=gi=0∑ni̸=j∏(k−x[i])(x[i]−x[j])yi设ti=yi∏j!=ixi−xjt_{i}=\frac{y_{i}}{\prod_{j != i} x_{i}-x_{j}}ti=∏j!=ixi−xjyi
f(k)=g∑i=0nti(k−x[i])f(k)=g \sum_{i=0}^{n} \frac{t_{i}}{(k-x[i])} f(k)=gi=0∑n(k−x[i])ti
这样每次新加入一个点的时候只需要计算它的 tititi 即可
应用
拉格朗日插值法求自然数幂的前缀和
模板
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int N = 5e4 + 10;int t, e;
ll n, k;//求过 (xi, yi) 的 e-1 次的多项式
ll inv[N]; //逆元
ll a[N]; //1 到 e,e个点, 也就是yi,视题目而定
ll pre[N], suf[N]; //前缀积 后缀积
ll fac[N]; //阶乘的逆元ll q_pow(ll x, ll y){ll ans = 1;while(y){if(y&1)ans = ans * x % mod;x = x * x % mod, y >>= 1;}return ans;
}ll solve(ll x, int e){ // 1 到 e,e个点插值if(x <= e) //直接返回return a[x];x %= mod;ll ans = 0;pre[0] = suf[e+1] = 1; //边界for(ll i = 1; i <= e; i++){ //(x-i) 前缀积pre[i] = pre[i - 1] * (x - i) % mod; }for (ll i = e; i >=1 ; i--){ //(x-i) 后缀积suf[i] = suf[i + 1] * (x - i) % mod; }for(ll i = 1; i <= e; i++){ll f = fac[i - 1] * fac[e - i] % mod; //从 0 到 e时,fac[i-1] 变为 fac[i];f = (e - i) & 1 ? -f : f; //判断正负(ans += a[i] * f % mod * pre[i - 1] % mod * suf[i + 1]) %= mod;}ans += ans < 0 ? mod : 0;return ans;
}int main()
{for(ll i = 1; i < N; i++){ //预处理逆元inv[i] = q_pow(i, mod - 2);}fac[0] = 1;for(int i = 1; i < N; i++){ //预处理阶乘逆元fac[i] = fac[i - 1] * inv[i] % mod;}cout << solve(n, e) << endl;return 0;
}
参考
https://www.cnblogs.com/zwfymqz/p/10063039.html#_label1_0
https://riteme.site/blog/2017-3-18/lagrange-interpolation.html
https://www.cnblogs.com/ECJTUACM-873284962/p/6833391.html#_labelTop
插值详解:https://www.cnblogs.com/duye/p/8671820.html
拉格朗日插值法总结模板(1~n)相关推荐
- 拉格朗日插值法与牛顿插值多项式
多项式插值 先有一个函数 f ( x ) f(x) f(x),如果给定在区间 [ a , b ] [a,b] [a,b]上的 n + 1 n+1 n+1个点 a < = x 0 < x 1 ...
- C++ 拉格朗日插值法优化 DP
文章目录 拉格朗日插值法 简介 拉格朗日插值法 模板 DP 优化 思路 例题一 分析 代码 例题二 分析 代码 A trick 拉格朗日插值法 简介 众所周知,nnn 个点 (xi,yi)(x_i, ...
- rstudio拉格朗日插值法_拉格朗日插值法学习笔记
拉格朗日插值法是一个根据点对求回原函数的算法,原理挺好懂的. 原理和优化方法上面的大佬都讲得很好. 其实主要就是这个式子: 然后暴力算这个式子的话是每求一项f(k)的时间复杂度都是n^2. 这个时间很 ...
- Python实现拉格朗日插值法
已知sinx的一组x,y对应关系,用拉格朗日插值法估计sin(0.3367)的值. x x0.32 0.34 0.36 y 0.314567 0.333487 0.352274 / / class I ...
- 拉格朗日插值法(Lagrange插值法)
插值介绍: 在离散数据的基础上补插连续函数,使得这条连续曲线通过全部给定的离散数据点. 插值是离散函数逼近的重要方法,利用它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值. 这是百度百 ...
- 2021-01-07 matlab数值分析 插值法 拉格朗日插值法 牛顿插值法
matlab数值分析 插值法 1 拉格朗日插值法 function yh=lagrange(x,y,xh) n=length(x); m=length(xh); yh=zeros(1,m); for ...
- 拉格朗日c语言实验报告,拉格朗日插值法C语言的实现(实验报告)(9页)-原创力文档...
韩山师范学院 C语言程序设计 实验名称: 实验一:拉格朗日插值法C语言的实现 日期: 2011-9-19 任课教师: 赖国明 专业: 数学与应用数学 学号: 2009111437 姓名: 郑永锋 [实 ...
- 拉格朗日插值法matlab上机,拉格朗日插值法使用MATLAB做的例题
<拉格朗日插值法使用MATLAB做的例题>由会员分享,可在线阅读,更多相关<拉格朗日插值法使用MATLAB做的例题(2页珍藏版)>请在人人文库网上搜索. 1.一物体廓线数据如下 ...
- 拉格朗日插值法(Lagrange)
拉格朗日插值法是基于基函数的插值方法,插值多项式可以表示为: 其中称为 i 次基函数 Matlab中拉格朗日插值法函数为:Language 功能:求已知点数据点的拉格朗日多项式 调用格式:f=Lagr ...
- 【BZOJ3453】XLkxc [拉格朗日插值法]
XLkxc Time Limit: 20 Sec Memory Limit: 128 MB [Submit][Status][Discuss] Description 给定 k,a,n,d,p f( ...
最新文章
- LaTex公式编辑方法
- 如何将C# 7类库升级到C# 8?使用可空引用类型
- golang 字符串md5 生成方式
- python语言属于-Python语言属于( )。_学小易找答案
- tf.nn.embedding_lookup函数的用法
- 获取整数的位数_从NMEA0183到GNSS定位数据获取(二)软件篇
- 如何融入到更积极的环境,促进技术提升
- WebService C#开发/调用
- mac笔记本怎么外接显示屏_win to go的安装与Macbook pro外接eGPU开启
- 一年收入多少才能支撑自驾环游中国?
- 怎么在html中加横条,如何在HTML中插入一行?html横线标签hr全新讲解
- null和空 not null
- EasyStreamClient对接海康流媒体V4.X——SDK对接关键函数记录
- 关于es cpu安装黑苹果,并实现变频
- python实例02,__str__只能返回字符串
- python--step-01
- 逆向工程(MyBatis)
- Java数据类型:基本数据类型和引用数据类型
- input 标签 autofill属性生效导致的输入框背景色变成黄色(或其他色)的解决办法
- vvic、lazada等国内小众电商平台商品详情API调用展示
热门文章
- 毕小朋《精通Android studio》读后感,以及电子书百度网盘PDF下载
- [C++]求模与求余运算
- 域名转移记录,从百度云转出至阿里云转入
- seo与sem的区别与联系(大全篇)
- SEM 与 SEO 之间的区别与联系
- 给定两个水壶,一个可以装4升水,一个能装3升水,水壶上没有任何度量标记。有一水龙头可以用来往壶中灌水。问题是怎样在能装4升的水壶里面恰好只装2升水
- ps入门第17天_模糊与锐化 案例:基础磨皮效果_ps修图_ps磨皮_ps高低频修图
- 张尧学等人获奖,理由不充分
- 辞职文案火了,程序员的辞职理由要命不要钱。
- 学习使用大数据数据采集工具(python)