cumulative_simpson#
- scipy.integrate.cumulative_simpson(y, *, x=None, dx=1.0, axis=-1, initial=None)[源代码]#
使用复合辛普森 1/3 法则对 y(x) 进行累积积分。每个点的样本积分是通过假设每个点与两个相邻点之间存在二次关系来计算的。
- 参数:
- yarray_like
要积分的值。沿 axis 至少需要一个点。如果沿 axis 提供的点数少于或等于两个,则无法进行辛普森积分,并且结果将使用
cumulative_trapezoid
计算。- xarray_like, 可选
要沿其积分的坐标。必须具有与 y 相同的形状,或者必须是 1D,且沿 axis 的长度与 y 相同。x 也必须沿 axis 严格递增。如果 x 为 None(默认),则使用 y 中连续元素之间的间距 dx 执行积分。
- dx标量或 array_like, 可选
y 的元素之间的间距。仅当 x 为 None 时使用。可以是浮点数,也可以是与 y 形状相同的数组,但沿 axis 的长度为 1。默认值为 1.0。
- axisint, 可选
指定要沿其积分的轴。默认值为 -1(最后一个轴)。
- initial标量或 array_like, 可选
如果给出,则将此值插入到返回结果的开头,并将其添加到其余结果中。默认值为 None,这意味着不返回
x[0]
处的值,并且 res 沿积分轴的元素比 y 少一个。可以是浮点数,也可以是与 y 形状相同的数组,但沿 axis 的长度为 1。
- 返回:
- resndarray
沿 axis 对 y 进行累积积分的结果。如果 initial 为 None,则形状为沿积分轴的值比 y 少一个。如果给出了 initial,则形状与 y 的形状相同。
另请参阅
numpy.cumsum
cumulative_trapezoid
使用复合梯形法则进行累积积分
simpson
使用复合辛普森法则对采样数据进行积分
注释
在 1.12.0 版本中添加。
复合辛普森 1/3 法可用于近似采样输入函数 \(y(x)\) 的定积分 [1]。该方法假设在包含任意三个连续采样点的区间上存在二次关系。
考虑三个连续的点:\((x_1, y_1), (x_2, y_2), (x_3, y_3)\)。
假设这三个点之间存在二次关系,则 \(x_1\) 和 \(x_2\) 之间的子区间上的积分由 [2] 的公式 (8) 给出
\[\begin{split}\int_{x_1}^{x_2} y(x) dx\ &= \frac{x_2-x_1}{6}\left[\ \left\{3-\frac{x_2-x_1}{x_3-x_1}\right\} y_1 + \ \left\{3 + \frac{(x_2-x_1)^2}{(x_3-x_2)(x_3-x_1)} + \ \frac{x_2-x_1}{x_3-x_1}\right\} y_2\\ - \frac{(x_2-x_1)^2}{(x_3-x_2)(x_3-x_1)} y_3\right]\end{split}\]\(x_2\) 和 \(x_3\) 之间的积分通过交换 \(x_1\) 和 \(x_3\) 的位置得出。分别估计每个子区间的积分,然后累加求和以获得最终结果。
对于等间距的样本,如果函数是三次或更低阶的多项式 [1] 且子区间数为偶数,则结果是精确的。否则,对于二次或更低阶的多项式,积分是精确的。
参考文献
[2]Cartwright, Kenneth V. Simpson’s Rule Cumulative Integration with MS Excel and Irregularly-spaced Data. Journal of Mathematical Sciences and Mathematics Education. 12 (2): 1-9
示例
>>> from scipy import integrate >>> import numpy as np >>> import matplotlib.pyplot as plt >>> x = np.linspace(-2, 2, num=20) >>> y = x**2 >>> y_int = integrate.cumulative_simpson(y, x=x, initial=0) >>> fig, ax = plt.subplots() >>> ax.plot(x, y_int, 'ro', x, x**3/3 - (x[0])**3/3, 'b-') >>> ax.grid() >>> plt.show()
cumulative_simpson
的输出类似于迭代调用simpson
并逐渐增加积分上限,但不完全相同。>>> def cumulative_simpson_reference(y, x): ... return np.asarray([integrate.simpson(y[:i], x=x[:i]) ... for i in range(2, len(y) + 1)]) >>> >>> rng = np.random.default_rng() >>> x, y = rng.random(size=(2, 10)) >>> x.sort() >>> >>> res = integrate.cumulative_simpson(y, x=x) >>> ref = cumulative_simpson_reference(y, x) >>> equal = np.abs(res - ref) < 1e-15 >>> equal # not equal when `simpson` has even number of subintervals array([False, True, False, True, False, True, False, True, True])
这是预期的:因为
cumulative_simpson
可以访问比simpson
更多的信息,因此它通常可以产生更准确的子区间基础积分估计值。