前言:

本文计算离散点微分和积分的内容,参考的是origin软件提供的算法。

鉴于在百度和谷歌搜索标题的结果不尽人意,因此想在此做一个详细的总结。

若阅读时间有限,可直接阅读第二或第三部分的代码及其运行结果。

若有疑问或者错误,欢迎评论区留言提问或者指正,谢谢。

一、原理解释

【微分部分】

大致含义:对于端点以外的散点,其导数为:与其相邻两点的斜率的平均值;                                而位于端点的散点,其导数为:与其最近一点的斜率。

Origin软件中离散点导数的计算公式

【积分部分】

大致含义:两点之间的积分,为两点连线,和两点对x轴的垂线,以及两垂足之间的线段所组成的梯形的面积。本文咱不探讨存在水平线baseline的情况下散点积分的数学面积(面积可正可负)与绝对面积(恒为正),感兴趣的读者可以点击参考文献4去阅读。

Origin软件中离散点积分的计算公式

注解:

1.梯形面积公式 = 1/2 * (上底+下底) * 高

2.x(i+1) - x(i)(含有i的括号内的式子均为下标):表示梯形的高

3.f(x(i+1))+f(x(i))(含有i的括号内的式子均为下标):表示梯形上下底之和

二、纯代码:

【微分部分】

# 定义计算离散点导数的函数
def cal_deriv(x, y):                  # x, y的类型均为列表diff_x = []                       # 用来存储x列表中的两数之差for i, j in zip(x[0::], x[1::]):  diff_x.append(j - i)diff_y = []                       # 用来存储y列表中的两数之差for i, j in zip(y[0::], y[1::]):diff_y.append(j - i)  slopes = []                       # 用来存储斜率for i in range(len(diff_y)):slopes.append(diff_y[i] / diff_x[i])deriv = []                        # 用来存储一阶导数for i, j in zip(slopes[0::], slopes[1::]):        deriv.append((0.5 * (i + j))) # 根据离散点导数的定义,计算并存储结果deriv.insert(0, slopes[0])        # (左)端点的导数即为与其最近点的斜率deriv.append(slopes[-1])          # (右)端点的导数即为与其最近点的斜率for i in deriv:                   # 打印结果,方便检查,调用时也可注释掉print(i)return deriv                      # 返回存储一阶导数结果的列表
x = [1/60, 1/30, 1/20, 1/15, 1/12, 1/10, 7/60, 2/15, 3/20, 1/6, 11/60]
y = [99.8014, 99.80255, 99.80633, 99.81218, 99.82422, 99.83488, 99.85151, 99.87169, 99.89393, 99.91125,99.92673]print(cal_deriv(x, y))# 运行结果
# 0.06899999999973261
# 0.14790000000004963
# 0.2889000000000408
# 0.5366999999998258
# 0.6810000000000114
# 0.8187000000002341
# 1.1043000000000804
# 1.2725999999997841
# 1.1867999999998349
# 0.9840000000002649
# 0.9288000000006493
# [0.06899999999973261, 0.14790000000004963, 0.2889000000000408, 0.5366999999998258, 0.6810000000000114, 0.8187000000002341, 1.1043000000000804, 1.2725999999997841, 1.1867999999998349, 0.9840000000002649, 0.9288000000006493]

为便于理解,展示手算 "x=1/60" 和 "x=1/30" 处(一阶)导数的过程:

x = 1/60:

diff_x = 1/30 - 1/60 = 1/60

diff_y = 99.80255 - 99.8014 = 0.00115

点 "x = 1/60" (端点) 与其相邻点的斜率为:slopes = diff_y / diff_x = 0.00115 / (1/60) = 0.069

点 "x=1/60" 处的导数为:deriv(x = 1/60) = 0.069 (也可0.5 * (0.069+0.069) = 0.069)

x = 1/30:

diff_x = 1/20 - 1/30 = 1/60 (由于x的间距均为1/60,因此也可不重复计算)

diff_y = [99.80255 - 99.8014, 99.80633 - 99.80255] = [0.00115, 0.00378]

点 "x = 1/30" 与其相邻两点的斜率分别为:

slopes = [0.00115 / (1/60), 0.00378 / (1/60)] = [0.069, 0.2268]

点 "x=1/30" 处的导数为:deriv(x = 1/30) = 0.5 * ( 0.2268 + 0.069) = 0.1479

注意:设列表x和y的元素个数都为n,则存储两两之差结果的列表diff_x和diff_y的元素个数均为n-1,slopes的元素个数也为n-1;在对deriv进行insert和append操作之前,deriv的元素个数为n-2(原因是对slopes计算两两平均)。为了方便计算,在deriv的两端插入slopes的两端值,这样并不影响结果的正确性(本身+本身的和乘以0.5还是等于本身)。

【微分部分:补充计算二阶导数的函数】

# 补充:计算二阶导数的函数
# 注释掉cal_deriv(x, y)函数中打印结果的那两行以及最后一行return,并添加如下函数即可:def cal_2nd_deriv(x,y):return cal_deriv(x, cal_deriv(x, y))# 用了迭代的思路:将一阶导数的结果作为y再次输入,而x保持不变
x = [1/60, 1/30, 1/20, 1/15, 1/12, 1/10, 7/60, 2/15, 3/20, 1/6, 11/60]
y = [99.8014, 99.80255, 99.80633, 99.81218, 99.82422, 99.83488, 99.85151, 99.87169, 99.89393, 99.91125,99.92673]
cal_2nd_deriv(x,y)# 运行结果
# [4.734000000019021,
#  6.597000000009245,
#  11.663999999993285,
#  11.76299999999912,
#  8.46000000001225,
#  12.699000000002073,
#  13.616999999986504,
#  2.4749999999926335,
#  -8.657999999985579,
#  -7.739999999975568,
#  -3.3119999999769343]

为便于理解,展示手算 “x=1/60” 和 “x=1/30” 处二阶导数的过程:

x = 1/60:

diff_x = 1/30 - 1/60 = 1/60

diff_y (diff_deriv) = 0.1479 - 0.069 = 0.0789

点 "x = 1/60" (端点) 与其相邻点的斜率为:slopes = diff_y / diff_x = 0.0789 / (1/60) = 4.734

点 "x=1/60" 处的二阶导数为:2nd_deriv(x = 1/60) = 4.734 (也可0.5 * (4.734 + 4.734) = 4.734)

x = 1/30:

diff_x = 1/20 - 1/30 = 1/60 (由于x的间距均为1/60,因此也可不重复计算)

diff_y (diff_deriv) = [0.1479 - 0.069, 0.2889 - 0.1479] = [0.0789, 0.141]

点 "x = 1/30" 与其相邻两点的斜率分别为:

slopes = [0.0789 / (1/60), 0.141 / (1/60)] = [4.734, 8.46]

点 "x=1/30" 处的二阶导数为:2nd_deriv(x = 1/30) = 0.5 * (4.734 + 8.46) = 6.597

【积分部分】

import numpy as np
import scipy
from scipy.integrate import simps # 用于计算积分
import matplotlib.pyplot as plt   # 用于画图x = np.arange(11)       # 构造一个从0到10的等差数列数组,作为横轴取值
y = np.arange(11)       # 构造一个从0到10的等差数列数组,作为纵轴取值
integrals = []          # 用于存储积分for i in range(len(y)): # 计算梯形的面积,由于是累加,所以是切片"i+1"integrals.append(scipy.integrate.trapz(y[:i + 1], x[:i + 1]))
for i in integrals:     # 输出结果(存储的积分)print(i)plt.plot(x, y)
plt.show()
# 定义计算离散点积分的函数
def cal_integral(x,y):import scipyfrom scipy.integrate import simps # 用于计算积分integrals = []for i in range(len(y)): # 计算梯形的面积,由于是累加,所以是切片"i+1"integrals.append(scipy.integrate.trapz(y[:i + 1], x[:i + 1]))return integrals
import numpy as np
x = np.arange(11)       # 构造一个从1到10的等差数列数组,作为横轴取值
y = np.arange(11)       # 构造一个从1到10的等差数列数组,作为纵轴取值cal_integral(x,y)# 运行结果
# [0.0, 0.5, 2.0, 4.5, 8.0, 12.5, 18.0, 24.5, 32.0, 40.5, 50.0]

三、代码及其运行结果

【微分部分】

百度经验提供的在Origin软件中计算导数的参考结果

与百度经验提供的参考结果非常接近(精确到小数点后三到四位)

与百度经验提供的参考结果非常接近(精确到小数点后三到四位),以及结果对应的折线图

注意:这里的第11个x(11/60)由于处在列表x的末端,其对应的导数不准确(上述结果为0.9288,而实际为0.90471)。这是因为 "x=11/60" 在上述示例中位于右端点而实际(百度经验中)为非端点

【微分部分:补充计算二阶导数的函数】

基于导数函数,构造计算二阶导数函数的代码及其运行结果

【积分部分】

函数 "y = x" 在 "x=0" 到 "x=10" 上的积分结果

四、参考文献

【微分部分】

1."Algorithm of calculating derivatives of discrete data in origin software"

2.百度经验:如何使用origin对数据进行一阶求导?

3.Python | Calculate difference between adjacent elements in given list

【积分部分】

4."Algorithm of calculating integrals of discrete data in origin software"

5.Integrating Discrete point in Python

修改记录:

版本号

日期

修改内容

v0.1

2020-08-28

第一版发布

v0.2 2020-09-20 修改了积分部分关于等差数列的小错误: np.arange(10)的"10"改为"11"

python 计算离散点的微分和积分(超详细)相关推荐

  1. python离散积分_python 计算离散点的微分和积分(超详细)

    前言: 本文计算离散点微分和积分的内容,参考的是origin软件提供的算法. 鉴于在百度和谷歌搜索标题的结果不尽人意,因此想在此做一个详细的总结. 若阅读时间有限,可直接阅读第二或第三部分的代码及其运 ...

  2. 基于python计算包含贝塞尔函数的积分

    基于python计算圆形回线瞬变电磁场 难点是贝塞尔函数的求解,目前python无该函数,但在scipy.special中,封装了如下Bessel函数. 这些不同类型的Bessel函数,具有相似的输入 ...

  3. 用Python实现问卷星自动填写(超详细!!!)

    用Python实现问卷星自动填写(超详细!!!) 前言 一.配置环境 1.1安装依赖 1.2安装驱动 二.实战处理 2.1.引入库函数 2.2.程序所需函数详解 (1)自定义单选函数 (2)自定义多选 ...

  4. python怎么爬取b站_【Python爬虫实例学习篇】——4、超详细爬取bilibili视频

    [Python爬虫实例学习篇]--4.超详细爬取bilibili视频 由于经常在B站上学习,但无奈于家里网络太差,在线观看卡顿严重,于是萌生了下载视频的想法(如果只是单纯想下载视频,请用you-get ...

  5. 微积分之曲线积分与曲面积分超详细知识框架

    微积分之曲线积分与曲面积分超详细知识框架 这个是我在学完了这一章的时候画的,我个人觉得吧,大家千万不要以为制作思维导图花费时间,其实你在做思维框架的时候,是对整个这一章所有知识的一种大局观,我们能够在 ...

  6. 万字长文爆肝Python基础入门【第二弹、超详细数据类型总结】

    目录 一.建立一个数据火车--列表 1.创建列表 2.列表元素的获取 3.列表元素的添加 4.列表元素的删除 5.列表元素的修改 二.列表的亲兄弟--元组 1.创建元组 2.元组元素的获取 3.元组和 ...

  7. python飞机游戏视频教程_10分钟教你用Python做个打飞机小游戏超详细教程

    01 前言 这次还是用python的pygame库来做的游戏.关于这个库的内容,读者可以上网了解一下.本文只讲解用到的知识.代码参考自网上,自己也做了一点代码简化.尽量把最核心的方面用最简单的方式呈现 ...

  8. 教你用Python做个打飞机小游戏超详细教程

    01 前言 这次还是用python的pygame库来做的游戏.关于这个库的内容,读者可以上网了解一下.本文只讲解用到的知识.代码参考自网上,自己也做了一点代码简化.尽量把最核心的方面用最简单的方式呈现 ...

  9. python能打包成apk吗_超详细APK打包教程

    首先发官方的帮助文档地址 http://miaowm5.github.io/RMMV-F1/ 然后点击"转换为Android 程序 第一步:安装各种环境.参照官方的文档一个一个安装好即可.我 ...

最新文章

  1. rust怎么把门拿下来_皮肤好的女生都是怎么护肤的?快拿小本本记下来
  2. node.js java web_Node.js 做 Web 后端优势为什么这么大?
  3. jsch 移动服务器上文件,jsch上传文件到服务器
  4. Typesafe公司正式更名为Lightbend公司
  5. java maven调用hbase
  6. linux内核那些事之E820
  7. 【STM32】HAL库 STM32CubeMX教程五----看门狗(独立看门狗,窗口看门狗)
  8. Javascript特效:图片切换(类似于电商网站图片查看)的封装实现和闭包实现
  9. mysql可以考什么证_MySQL有没有什么比较权威的认证考试呢?
  10. 直播短视频源码要如何开发?简单几步教你快速开发!
  11. 微软应用商店打不开代码代码: 0x80131500
  12. 直播视频卡顿延迟时如何优化
  13. 计算机应用基础第四章电子表格测试,2019年计算机应用基础第四章测试答案
  14. pod中mysql配置文件修改_Pod中的secret,configmap,downwardapi的使用记录
  15. 关于运行npm install报[..................] / idealTree:WEB-48403: sill idealTree buildDeps的问题
  16. 微信小程序—刷脸实名认证
  17. wi7计算机如何查看隐藏的文件夹,win7隐藏的文件夹怎么显示?隐藏文件夹查看及设置方法...
  18. 线性规划模型应用的2个案例
  19. Flutter Icon
  20. 如何解除excel只读文件

热门文章

  1. 删除子文件夹[字典树 + go变量 + strings.builder的copyCheck()]
  2. Git 使用过程中遇到的问题以及解决办法
  3. 新站长建设网站需要学习知识
  4. 《C语言入门经典》Ivor Horton第十章练习题3
  5. vue给html动态添加属性,Vue中怎么动态添加类名?
  6. Android 开发挑战赛 | 第 2 周: 倒计时器
  7. 何恺明团队新作FLIP:通过Masking扩展语言-图像预训练
  8. 使用yocs_velocity_smoother对机器人速度进行限制
  9. C# Math函数汇总
  10. Mac软件破解版下载地址