拉格朗日插值法——用Python进行数值计算
插值法的伟大作用我就不说了。。。。
那么贴代码?
首先说一下下面几点:
1. 已有的数据样本被称之为 “插值节点”
2. 对于特定插值节点,它所对应的插值函数是必定存在且唯一的(关于这个的证明我暂时不说了,如果哪天我回头看看我的blog有点寒碜,我再再补上)
也就是说对于同样的插值样本来说,用不同方法求得的插值函数本质上其实是一样的。
3. 拉格朗日插值法依赖于每个插值节点对应的插值基函数,也就是说每个插值节点都有对应的插值基函数。
4. 拉格朗日插值函数最终由所有插值节点中每个插值节点的纵坐标值与它对应的插值函数的积的和构成。
5. 也就是说拉格朗日插值法关键在于求基函数
6. 拉格朗日插值法并不好,当每一次加入新的插值节点的时候,所有的系数都要重算一遍
计算插值函数参数的最本质的方法是解下面的矩阵方程:

我先构造一组插值样本:
sr_x = [i for i in range(-50, 50, 10)]
sr_fx = [i**2 for i in sr_x]
sr_x 为样本的横坐标,sr_fx为样本的纵坐标,样本的定义域是[-50, 50],样本之间距离为10
纵坐标为横坐标的平方,也就是说这是一个二次函数 sr_fx = sr_x ^2
这样一组样本的图像是这样的:

然后我用这一组插值节点来获得每个节点对应的插值基函数:
基函数的计算公式是 li = (x - x0)(x - x1) ... (x - x(i-1))(x - x(i+1)) ... (x - xn)/(xi - x0)(xi - x1) ... (xi - x(i-1))(xi - x(i+1)) ... (xi - xn)
其中W = (x - x0)(x - x1) ... (x - x(i-1))(x - x(i+1)) ... (x - xn)
c = (xi - x0)(xi - x1) ... (xi - x(i-1))(xi - x(i+1)) ... (xi - xn)
因此 li = W / c
注意:在计算i的插值基函数的时候,公式c与W里面是没有被减数为Xi项的。(要是有的话W与c就为0了)
这一段代码是这样的:
def get_li(xi, x_set = []):
def li(Lx):
W = 1; c = 1
for each_x in x_set:
if each_x == xi:
continue
W = W * (Lx - each_x) for each_x in x_set:
if each_x == xi:
continue
c = c * (xi - each_x) # 这里一定要转成float类型,否则极易出现严重错误. 原因就不说了
return W / float(c)
return li
这段代码用到了闭包,这样可以返回一个基函数,并且这个函数以get_li的内部为上下文(上下文这个翻译总让人感觉怪怪的,似乎与写作文有某种联系)。
当获得基函数之后就是累加基函数与插值节点纵坐标的乘积构成拉格朗日插值函数了
这一段的代码是这样:
"""
@brief: 获得拉格朗日插值函数
@param: x 插值节点的横坐标集合
@param: fx 插值节点的纵坐标集合
@return: 参数所指定的插值节点集合对应的插值函数
"""
def get_Lxfunc(x = [], fx = []):
set_of_lifunc = []
for each in x: # 获得每个插值点的基函数
lifunc = get_li(each, x)
set_of_lifunc.append(lifunc) # 将集合x中的每个元素对应的插值基函数保存 def Lxfunc(Lx):
result = 0
for index in range(len(x)):
result = result + fx[index]*set_of_lifunc[index](Lx) #根据根据拉格朗日插值法计算Lx的值
print fx[index]
return result return Lxfunc
到这里就大功告成了,我用上面给的插值节点计算出的插值函数是这样的:

完整代码如下:
# -*- coding: utf-8 -*-
"""
Created on Wed Nov 16 13:26:58 2016 @author: tete
@brief: 拉格朗日插值法
""" import matplotlib.pyplot as plt """
@brief: 获得拉格朗日插值基函数
@param: xi xi为第i个插值节点的横坐标
@param: x_set 整个插值节点集合
@return: 返回值为参数xi对应的插值基函数
"""
def get_li(xi, x_set = []):
def li(Lx):
W = 1; c = 1
for each_x in x_set:
if each_x == xi:
continue
W = W * (Lx - each_x) for each_x in x_set:
if each_x == xi:
continue
c = c * (xi - each_x) # 这里一定要转成float类型,否则极易出现严重错误. 原因就不说了
return W / float(c)
return li """
@brief: 获得拉格朗日插值函数
@param: x 插值节点的横坐标集合
@param: fx 插值节点的纵坐标集合
@return: 参数所指定的插值节点集合对应的插值函数
"""
def get_Lxfunc(x = [], fx = []):
set_of_lifunc = []
for each in x: # 获得每个插值点的基函数
lifunc = get_li(each, x)
set_of_lifunc.append(lifunc) # 将集合x中的每个元素对应的插值基函数保存 def Lxfunc(Lx):
result = 0
for index in range(len(x)):
result = result + fx[index]*set_of_lifunc[index](Lx) #根据根据拉格朗日插值法计算Lx的值
print fx[index]
return result return Lxfunc """
demo:
"""
if __name__ == '__main__': ''' 插值节点, 这里用二次函数生成插值节点,每两个节点x轴距离位10 '''
sr_x = [i for i in range(-50, 50, 10)]
sr_fx = [i**2 for i in sr_x] Lx = get_Lxfunc(sr_x, sr_fx) # 获得插值函数
tmp_x = [i for i in range(-45, 45)] # 测试用例
tmp_y = [Lx(i) for i in tmp_x] # 根据插值函数获得测试用例的纵坐标 ''' 画图 '''
plt.figure("play")
ax1 = plt.subplot(111)
plt.sca(ax1)
plt.plot(sr_x, sr_fx, linestyle = ' ', marker='o', color='b')
plt.plot(tmp_x, tmp_y, linestyle = '--', color='r')
plt.show()
拉格朗日插值法——用Python进行数值计算的更多相关文章
- 牛顿插值法——用Python进行数值计算
拉格朗日插值法的最大毛病就是每次引入一个新的插值节点,基函数都要发生变化,这在一些实际生产环境中是不合适的,有时候会不断的有新的测量数据加入插值节点集, 因此,通过寻找n个插值节点构造的的插值函数与n ...
- Matlab数值计算示例: 牛顿插值法、LU分解法、拉格朗日插值法、牛顿插值法
本文源于一次课题作业,部分自己写的,部分借用了网上的demo 牛顿迭代法(1) x=1:0.01:2; y=x.^3-x.^2+sin(x)-1; plot(x,y,'linewidth',2);gr ...
- 拉格朗日插值法--python
数据插补 常见插补方法 插值法--拉格朗日插值法 根据数学知识可知,对于平面上已知的n个点(无两点在一条直线上可以找到n-1次多项式 ,使次多项式曲线过这n个点. 1)求已知过n个点的n-1次多项式: ...
- CPP&MATLAB实现拉格朗日插值法
开始学习MATLAB(R和Python先放一放...),老师推荐一本书,看完基础就是各种算法...首先是各种插值.先说拉格朗日插值法,这原理楼主完全不懂的,查的维基百科,好久才看懂.那里讲的很详细,这 ...
- 埃尔米特插值问题——用Python进行数值计算
当插值的要求涉及到对插值函数导数的要求时,普通插值问题就变为埃尔米特插值问题.拉格朗日插值和牛顿插值的要求较低,只需要插值函数的函数值在插值点与被插函数的值相等,以此来使得在其它非插值节点插值函数的值 ...
- python与数值计算环境搭建
数值计算的编程的软件很多种,也见过一些编程绘图软件的对比. 利用Python进行数值计算,需要用到numpy(矩阵) ,scipy(公式符号), matplotlib(绘图)这些工具包. 1.Linu ...
- codeforces 622F. The Sum of the k-th Powers 拉格朗日插值法
题目链接 求sigma(i : 1 to n)i^k. 为了做这个题这两天真是补了不少数论, 之前连乘法逆元都不知道... 关于拉格朗日插值法, 我是看的这里http://www.guokr.com/ ...
- bzoj4559[JLoi2016]成绩比较 容斥+拉格朗日插值法
4559: [JLoi2016]成绩比较 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 261 Solved: 165[Submit][Status ...
- 集训DAYn——拉格朗日插值法
看zzq大佬的博客,看到了这个看似很深奥的东西,实际很简单(反正比FFT简单,我是一个要被FFT整疯了的孩子) 拉格朗日插值法 是什么 可以找到一个多项式,其恰好在各个观测点取到观测到的值.这样的多项 ...
随机推荐
- ASP.NET Aries 入门开发教程5:自定义列表页工具栏区
前言: 抓紧时间,继续写教程,因为发现用户期待的内容,都在业务处理那一块. 不得不继续勤劳了. 这节主要介绍工具栏区的玩法. 工具栏的默认介绍: 工具栏默认包括5个按钮,根据不同的权限决定显示: 添加 ...
- DBImport V3.7版本发布及软件稳定性(自动退出问题)解决过程分享
DBImport V3.7介绍: 1:先上图,再介绍亮点功能: 主要的升级功能为: 1:增加(Truncate Table)清表再插入功能: 清掉再插,可以保证两个库的数据一致,自己很喜欢这个功能. ...
- QT5利用chromium内核与HTML页面交互
在QT5.4之前,做QT开发浏览器只能选择QWebkit,但是有过使用的都会发现,这个webkit不是出奇的慢,简直是慢的令人发指,Release模式下还行,debug下你就无语了,但是webkit毕 ...
- Asp.net Core准备工作
1.安装环境 安装.Net Core SDK 安装VS2015 Update3 安装DotNetCore.1.0.1-VS2015Tools.Preview2.0.2.exe 2.新建Core工程 项 ...
- Entity Framework的启动速度优化
最近开发的服务放到IIS上寄宿之后,遇到一些现象,比如刚部署之后,第一次启动很慢:程序放置一会儿,再次请求也会比较慢.比如第一个问题,可以解释为初次请求某一个服务的时候,需要把程序集加载到内存中可能比 ...
- 如何通过Git GUI将自己本地的项目上传至Github
最近在学习node.js和react,顺便复习了下AngluarJS相关的东西,写了些小demo想放在GitHub上,之前仅限于只申请了GitHub账号从没用过,今天花半天时间查资料认真学习Githu ...
- Autofac 的点滴
泛型类型的注册和使用 public interface IRepository<T> where T:class { } public interface ISchoolDetailRep ...
- 初探java中this的用法
一般this在各类语言中都表示“调用当前函数的对象”,java中也存在这种用法: public class Leaf { int i = 0; Leaf increment(){ i++; retur ...
- mono -图片处理
这篇文章中您将了解到以下内容 保存Bitmap WebClient文件上传 向服务端传递数据 保存Bitmap 做移动端开发,图片上传下载是最普通的需求了. 在mono for android中按照资 ...
- mono for android 用ISharedPreferences 进行状态保持 会话保持 应用程序首选项保存
由于项目需要 要保持用户登录状态 要进行状态保持 用途就好像asp.net的session一样 登录的时候进行保存 ISharedPreferences shared = GetSharedPrefe ...