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通过apply使用元祖和列表调用函数实例
May 26 Python
python查看zip包中文件及大小的方法
Jul 09 Python
在Python的Flask框架中构建Web表单的教程
Jun 04 Python
浅谈Python实现Apriori算法介绍
Dec 20 Python
Window 64位下python3.6.2环境搭建图文教程
Sep 19 Python
Python3按一定数据位数格式处理bin文件的方法
Jan 24 Python
python实现一个简单的ping工具方法
Jan 31 Python
Python这样操作能存储100多万行的xlsx文件
Apr 16 Python
django 通过url实现简单的权限控制的例子
Aug 16 Python
如何基于Python实现数字类型转换
Feb 07 Python
Python新手学习装饰器
Jun 04 Python
Python实现归一化算法详情
Mar 18 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中取得URL的根域名的代码
2011/03/23 PHP
yii gridview实现时间段筛选功能
2017/08/15 PHP
TP5框架实现的数据库备份功能示例
2020/04/05 PHP
mouse_on_title.js
2006/08/25 Javascript
jquery 子窗口操作父窗口的代码
2009/09/21 Javascript
javascript中创建对象的三种常用方法
2010/12/30 Javascript
远离JS灾难css灾难之 js私有函数和css选择器作为容器
2011/12/11 Javascript
JS实现定时页面弹出类似QQ新闻的提示框
2013/11/07 Javascript
js调用打印机打印网页字体总是缩小一号的解决方法
2014/01/24 Javascript
利用jquery.qrcode在页面上生成二维码且支持中文
2014/02/12 Javascript
Javascript基础教程之switch语句
2015/01/18 Javascript
Javascript中call和apply函数的比较和使用实例
2015/02/03 Javascript
MVVM模式中ViewModel和View、Model有什么区别?
2015/06/19 Javascript
JavaScript实现添加、查找、删除元素
2015/07/02 Javascript
Angularjs的ng-repeat中去除重复数据的方法
2016/08/05 Javascript
微信小程序 绘图之饼图实现
2016/10/24 Javascript
nodejs连接mongodb数据库实现增删改查
2016/12/01 NodeJs
js实现随机抽选效果、随机抽选红色球效果
2017/01/13 Javascript
详解在AngularJS的controller外部直接获取$scope
2017/06/02 Javascript
如何为你的JavaScript代码日志着色详解
2019/04/08 Javascript
express + jwt + postMan验证实现持久化登录
2019/06/05 Javascript
使用Python中PDB模块中的命令来调试Python代码的教程
2015/03/30 Python
Python实现找出数组中第2大数字的方法示例
2018/03/26 Python
Python设计模式之策略模式实例详解
2019/01/21 Python
Python queue队列原理与应用案例分析
2019/09/27 Python
Numpy与Pytorch 矩阵操作方式
2019/12/27 Python
python matplotlib.pyplot.plot()参数用法
2020/04/14 Python
Python 爬虫性能相关总结
2020/08/03 Python
详解python tkinter包获取本地绝对路径(以获取图片并展示)
2020/09/04 Python
详解如何修改jupyter notebook的默认目录和默认浏览器
2021/01/24 Python
一款基于css3和jquery实现的动画显示弹出层按钮教程
2015/01/04 HTML / CSS
AmazeUI 评论列表的实现示例
2020/08/13 HTML / CSS
师范生求职自荐信
2014/06/14 职场文书
农村优秀教师事迹材料
2014/08/27 职场文书
市场调研项目授权委托书范本
2014/10/04 职场文书
Go语言使用select{}阻塞main函数介绍
2021/04/25 Golang