拉格朗日插值法——用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整疯了的孩子) 拉格朗日插值法 是什么 可以找到一个多项式,其恰好在各个观测点取到观测到的值.这样的多项 ...
随机推荐
- GreenDao 数据库:使用Raw文件夹下的数据库文件以及数据库升级
一.使用Raw文件夹下的数据库文件 在使用GreenDao框架时,数据库和数据表都是根据生成的框架代码来自动创建的,从生成的DaoMaster中的OpenHelper类可以看出: public sta ...
- JS调用Android、Ios原生控件
在上一篇博客中已经和大家聊了,关于JS与Android.Ios原生控件之间相互通信的详细代码实现,今天我们一起聊一下JS调用Android.Ios通信的相同点和不同点,以便帮助我们在进行混合式开发时, ...
- mybatis_基础篇
一.认识mybatis: MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改 ...
- 多线程条件通行工具——AbstractQueuedSynchronizer
本文原创,转载请注明出处! 参考文章: <"JUC锁"03之 公平锁(一)> <"JUC锁"03之 公平锁(二)> AbstractOw ...
- 要想提高PHP的编程效率,你必须知道的要点
1.当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数.此函数执行起来相当快,因为它不做任何计算,只返回在zval 结构(C的内置数据结构,用于存储PHP变量)中存储 ...
- Python多线程爬虫爬取电影天堂资源
最近花些时间学习了一下Python,并写了一个多线程的爬虫程序来获取电影天堂上资源的迅雷下载地址,代码已经上传到GitHub上了,需要的同学可以自行下载.刚开始学习python希望可以获得宝贵的意见. ...
- Spring cache简单使用guava cache
Spring cache简单使用 前言 spring有一套和各种缓存的集成方式.类似于sl4j,你可以选择log框架实现,也一样可以实现缓存实现,比如ehcache,guava cache. [TOC ...
- JavaWeb——Servlet
一.基本概念 Servlet是运行在Web服务器上的小程序,通过http协议和客户端进行交互. 这里的客户端一般为浏览器,发送http请求(request)给服务器(如Tomcat).服务器接收到请求 ...
- maven-sprigmvc-mybatis配置
pom.xml配置 <?xml version="1.0"?> <project xsi:schemaLocation="http://maven.ap ...
- PMON failed to acquire latch, see PMON dump
前几天,一台Oracle数据库(Oracle Database 10g Release 10.2.0.4.0 - 64bit Production)监控出现"PMON failed to a ...