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 SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
May 06 Python
python 根据正则表达式提取指定的内容实例详解
Dec 04 Python
python3 shelve模块的详解
Jul 08 Python
Python实现的堆排序算法原理与用法实例分析
Nov 22 Python
vscode 远程调试python的方法
Dec 01 Python
Python爬取数据并写入MySQL数据库的实例
Jun 21 Python
对python中数据集划分函数StratifiedShuffleSplit的使用详解
Dec 11 Python
Python控制键盘鼠标pynput的详细用法
Jan 28 Python
基于django传递数据到后端的例子
Aug 16 Python
浅谈JupyterNotebook导出pdf解决中文的问题
Apr 22 Python
python实现单机五子棋
Aug 28 Python
Python实现拼音转换
Jun 07 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
Zend 输出产生XML解析错误
2009/03/03 PHP
php按字符无乱码截取中文的方法
2015/03/27 PHP
jQuery判断密码强度实现思路及代码
2013/04/24 Javascript
使用js解决由border属性引起的div宽度问题
2013/11/26 Javascript
js函数模拟显示桌面.scf程序示例
2014/04/20 Javascript
Javascript中prototype属性实现给内置对象添加新的方法
2015/05/14 Javascript
小巧强大的jquery layer弹窗弹层插件
2015/12/06 Javascript
基于jQuery实现放大镜特效
2020/10/19 Javascript
详解vue父子组件间传值(props)
2017/06/29 Javascript
微信小程序引用公共js里的方法的实例详解
2017/08/17 Javascript
Js面试算法详解
2018/04/08 Javascript
详解swipe使用及竖屏页面滚动方法
2018/06/28 Javascript
Vue-cli3项目配置Vue.config.js实战记录
2018/07/29 Javascript
在 Vue-CLI 中引入 simple-mock实现简易的 API Mock 接口数据模拟
2018/11/28 Javascript
vue 解决异步数据更新问题
2019/10/29 Javascript
javascript数组的定义及操作实例
2019/11/10 Javascript
vue prop传值类型检验方式
2020/07/30 Javascript
使用Vant完成通知栏Notify的提示操作
2020/11/11 Javascript
[34:27]DOTA2上海特级锦标赛B组败者赛 VG VS Spirit第一局
2016/02/26 DOTA
[44:01]2018DOTA2亚洲邀请赛3月30日 小组赛B组 EG VS paiN
2018/03/31 DOTA
实例讲解python函数式编程
2014/06/09 Python
使用Python的Twisted框架实现一个简单的服务器
2015/04/16 Python
python简单线程和协程学习心得(分享)
2017/06/14 Python
Python语言快速上手学习方法
2018/12/14 Python
Python查找数组中数值和下标相等的元素示例【二分查找】
2019/02/13 Python
Python 读取串口数据,动态绘图的示例
2019/07/02 Python
Python测试Kafka集群(pykafka)实例
2019/12/23 Python
canvas之自定义头像功能实现代码示例
2017/09/29 HTML / CSS
英国现代家具和装饰网站:PN Home
2018/08/16 全球购物
12月红领巾广播稿
2014/02/13 职场文书
考试诚信承诺书
2014/05/23 职场文书
解除租房协议书
2014/12/03 职场文书
2015年五四青年节活动总结
2015/02/10 职场文书
2015年中秋节主持词
2015/07/30 职场文书
教导处教学工作总结
2015/08/12 职场文书
教你怎么用python selenium实现自动化测试
2021/05/27 Python