python实现三次样条插值


Posted in Python onDecember 17, 2018

本文实例为大家分享了python实现三次样条插值的具体代码,供大家参考,具体内容如下

函数:

python实现三次样条插值

算法分析

三次样条插值。就是在分段插值的一种情况。

要求:

  • 在每个分段区间上是三次多项式(这就是三次样条中的三次的来源)
  • 在整个区间(开区间)上二阶导数连续(当然啦,这里主要是强调在节点上的连续)
  • 加上边界条件。边界条件只需要给出两个方程。构建一个方程组,就可以解出所有的参数。

这里话,根据第一类样条作为边界。(就是知道两端节点的导数数值,然后来做三次样条插值)

但是这里也分为两种情况,分别是这个数值是随便给的一个数,还是说根据函数的在对应点上数值给出。

情况一:两边导数数值给出

这里假设数值均为1。即 f′(x0)=f′(xn)=f′(xn)=1的情况。

情况一图像

python实现三次样条插值

情况一代码

import numpy as np
from sympy import *
import matplotlib.pyplot as plt


def f(x):
 return 1 / (1 + x ** 2)


def cal(begin, end, i):
 by = f(begin)
 ey = f(end)
 I = Ms[i] * ((end - n) ** 3) / 6 + Ms[i + 1] * ((n - begin) ** 3) / 6 + (by - Ms[i] / 6) * (end - n) + (
  ey - Ms[i + 1] / 6) * (n - begin)
 return I


def ff(x): # f[x0, x1, ..., xk]
 ans = 0
 for i in range(len(x)):
 temp = 1
 for j in range(len(x)):
  if i != j:
  temp *= (x[i] - x[j])
 ans += f(x[i]) / temp
 return ans


def calM():
 lam = [1] + [1 / 2] * 9
 miu = [1 / 2] * 9 + [1]
 # Y = 1 / (1 + n ** 2)
 # df = diff(Y, n)
 x = np.array(range(11)) - 5
 # ds = [6 * (ff(x[0:2]) - df.subs(n, x[0]))]
 ds = [6 * (ff(x[0:2]) - 1)]
 for i in range(9):
 ds.append(6 * ff(x[i: i + 3]))
 # ds.append(6 * (df.subs(n, x[10]) - ff(x[-2:])))
 ds.append(6 * (1 - ff(x[-2:])))
 Mat = np.eye(11, 11) * 2
 for i in range(11):
 if i == 0:
  Mat[i][1] = lam[i]
 elif i == 10:
  Mat[i][9] = miu[i - 1]
 else:
  Mat[i][i - 1] = miu[i - 1]
  Mat[i][i + 1] = lam[i]
 ds = np.mat(ds)
 Mat = np.mat(Mat)
 Ms = ds * Mat.I
 return Ms.tolist()[0]


def calnf(x):
 nf = []
 for i in range(len(x) - 1):
 nf.append(cal(x[i], x[i + 1], i))
 return nf


def calf(f, x):
 y = []
 for i in x:
 y.append(f.subs(n, i))
 return y


def nfSub(x, nf):
 tempx = np.array(range(11)) - 5
 dx = []
 for i in range(10):
 labelx = []
 for j in range(len(x)):
  if x[j] >= tempx[i] and x[j] < tempx[i + 1]:
  labelx.append(x[j])
  elif i == 9 and x[j] >= tempx[i] and x[j] <= tempx[i + 1]:
  labelx.append(x[j])
 dx = dx + calf(nf[i], labelx)
 return np.array(dx)


def draw(nf):
 plt.rcParams['font.sans-serif'] = ['SimHei']
 plt.rcParams['axes.unicode_minus'] = False
 x = np.linspace(-5, 5, 101)
 y = f(x)
 Ly = nfSub(x, nf)
 plt.plot(x, y, label='原函数')
 plt.plot(x, Ly, label='三次样条插值函数')
 plt.xlabel('x')
 plt.ylabel('y')
 plt.legend()

 plt.savefig('1.png')
 plt.show()


def lossCal(nf):
 x = np.linspace(-5, 5, 101)
 y = f(x)
 Ly = nfSub(x, nf)
 Ly = np.array(Ly)
 temp = Ly - y
 temp = abs(temp)
 print(temp.mean())


if __name__ == '__main__':
 x = np.array(range(11)) - 5
 y = f(x)

 n, m = symbols('n m')
 init_printing(use_unicode=True)
 Ms = calM()
 nf = calnf(x)
 draw(nf)
 lossCal(nf)

情况二:两边导数数值由函数本身算出

这里假设数值均为1。即 f′(xi)=S′(xi)(i=0,n)f′(xi)=S′(xi)(i=0,n)的情况。

情况二图像

python实现三次样条插值

情况二代码

import numpy as np
from sympy import *
import matplotlib.pyplot as plt


def f(x):
 return 1 / (1 + x ** 2)


def cal(begin, end, i):
 by = f(begin)
 ey = f(end)
 I = Ms[i] * ((end - n) ** 3) / 6 + Ms[i + 1] * ((n - begin) ** 3) / 6 + (by - Ms[i] / 6) * (end - n) + (
  ey - Ms[i + 1] / 6) * (n - begin)
 return I


def ff(x): # f[x0, x1, ..., xk]
 ans = 0
 for i in range(len(x)):
 temp = 1
 for j in range(len(x)):
  if i != j:
  temp *= (x[i] - x[j])
 ans += f(x[i]) / temp
 return ans


def calM():
 lam = [1] + [1 / 2] * 9
 miu = [1 / 2] * 9 + [1]
 Y = 1 / (1 + n ** 2)
 df = diff(Y, n)
 x = np.array(range(11)) - 5
 ds = [6 * (ff(x[0:2]) - df.subs(n, x[0]))]
 # ds = [6 * (ff(x[0:2]) - 1)]
 for i in range(9):
 ds.append(6 * ff(x[i: i + 3]))
 ds.append(6 * (df.subs(n, x[10]) - ff(x[-2:])))
 # ds.append(6 * (1 - ff(x[-2:])))
 Mat = np.eye(11, 11) * 2
 for i in range(11):
 if i == 0:
  Mat[i][1] = lam[i]
 elif i == 10:
  Mat[i][9] = miu[i - 1]
 else:
  Mat[i][i - 1] = miu[i - 1]
  Mat[i][i + 1] = lam[i]
 ds = np.mat(ds)
 Mat = np.mat(Mat)
 Ms = ds * Mat.I
 return Ms.tolist()[0]


def calnf(x):
 nf = []
 for i in range(len(x) - 1):
 nf.append(cal(x[i], x[i + 1], i))
 return nf


def calf(f, x):
 y = []
 for i in x:
 y.append(f.subs(n, i))
 return y


def nfSub(x, nf):
 tempx = np.array(range(11)) - 5
 dx = []
 for i in range(10):
 labelx = []
 for j in range(len(x)):
  if x[j] >= tempx[i] and x[j] < tempx[i + 1]:
  labelx.append(x[j])
  elif i == 9 and x[j] >= tempx[i] and x[j] <= tempx[i + 1]:
  labelx.append(x[j])
 dx = dx + calf(nf[i], labelx)
 return np.array(dx)


def draw(nf):
 plt.rcParams['font.sans-serif'] = ['SimHei']
 plt.rcParams['axes.unicode_minus'] = False
 x = np.linspace(-5, 5, 101)
 y = f(x)
 Ly = nfSub(x, nf)
 plt.plot(x, y, label='原函数')
 plt.plot(x, Ly, label='三次样条插值函数')
 plt.xlabel('x')
 plt.ylabel('y')
 plt.legend()

 plt.savefig('1.png')
 plt.show()


def lossCal(nf):
 x = np.linspace(-5, 5, 101)
 y = f(x)
 Ly = nfSub(x, nf)
 Ly = np.array(Ly)
 temp = Ly - y
 temp = abs(temp)
 print(temp.mean())


if __name__ == '__main__':
 x = np.array(range(11)) - 5
 y = f(x)

 n, m = symbols('n m')
 init_printing(use_unicode=True)
 Ms = calM()
 nf = calnf(x)
 draw(nf)
 lossCal(nf)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python dict remove数组删除(del,pop)
Mar 24 Python
python算法学习之计数排序实例
Dec 18 Python
爬山算法简介和Python实现实例
Apr 26 Python
Python操作列表之List.insert()方法的使用
May 20 Python
Python、PyCharm安装及使用方法(Mac版)详解
Apr 28 Python
Python中实现最小二乘法思路及实现代码
Jan 04 Python
python3下实现搜狗AI API的代码示例
Apr 10 Python
Python里字典的基本用法(包括嵌套字典)
Feb 27 Python
python将字符串转变成dict格式的实现
Nov 18 Python
Python实现自动打开电脑应用的示例代码
Apr 17 Python
Python tkinter实现日期选择器
Feb 22 Python
浅析python中特殊文件和特殊函数
Feb 24 Python
Python命名空间的本质和加载顺序
Dec 17 #Python
对python的unittest架构公共参数token提取方法详解
Dec 17 #Python
Python单元测试unittest的具体使用示例
Dec 17 #Python
Python使用Selenium爬取淘宝异步加载的数据方法
Dec 17 #Python
在scrapy中使用phantomJS实现异步爬取的方法
Dec 17 #Python
Python 通过调用接口获取公交信息的实例
Dec 17 #Python
python用插值法绘制平滑曲线
Feb 19 #Python
You might like
PHP 设计模式之观察者模式介绍
2012/02/22 PHP
php中如何同时使用session和cookie来保存用户登录信息
2013/07/05 PHP
PHP获取IP地址所在地信息的实例(使用纯真IP数据库qqwry.dat)
2016/11/15 PHP
解决laravel session失效的问题
2019/10/14 PHP
了解jQuery技巧来提高你的代码(个人觉得那个jquery的手册很不错)
2012/02/10 Javascript
使用 Node.js 做 Function Test实现方法
2013/10/25 Javascript
用js代码改变单选框选中状态的简单实例
2013/12/18 Javascript
jQuery学习笔记之基础中的基础
2015/01/19 Javascript
JavaScript通过prototype给对象定义属性用法实例
2015/03/23 Javascript
jQuery实现带动画效果的多级下拉菜单代码
2015/09/08 Javascript
javascript 闭包详解及简单实例应用
2016/12/31 Javascript
JS变量中有var定义和无var定义的区别以及es6中let命令和const命令
2017/02/19 Javascript
Javascript 详解封装from表单数据为json串进行ajax提交
2017/03/29 Javascript
详解React Native顶|底部导航使用小技巧
2017/09/14 Javascript
bootstrap Table服务端处理分页(后台是.net)
2017/10/19 Javascript
javaScript实现鼠标在文字上悬浮时弹出悬浮层效果
2020/04/12 Javascript
vue component 中引入less文件报错 Module build failed
2019/04/17 Javascript
微信小程序仿今日头条导航栏滚动解析
2019/08/20 Javascript
vue实现购物车功能(商品分类)
2020/04/20 Javascript
python 定时器,轮询定时器的实例
2019/02/20 Python
Python学习笔记之While循环用法分析
2019/08/14 Python
jupyter notebook 实现matplotlib图动态刷新
2020/04/22 Python
Anaconda+spyder+pycharm的pytorch配置详解(GPU)
2020/10/18 Python
HTML5移动端开发遇见的东西
2019/10/11 HTML / CSS
HTML5 WebGL 实现民航客机飞行监控系统
2019/07/25 HTML / CSS
HTML5在微信内置浏览器下右上角菜单的调整字体导致页面显示错乱的问题
2021/01/19 HTML / CSS
介绍下Java中==和equals的区别
2013/09/01 面试题
学生自我鉴定范文
2013/10/04 职场文书
大学生个人总结的自我评价
2013/10/05 职场文书
《月球之谜》教学反思
2014/04/10 职场文书
幼儿园区域活动总结
2014/05/08 职场文书
物业品质提升方案
2014/06/08 职场文书
群众路线四风自我剖析材料
2014/10/08 职场文书
工作检讨书范文
2015/01/23 职场文书
道歉信范文
2015/05/12 职场文书
2019求职信:应届生求职信范文
2019/04/24 职场文书