scipy.integrate.

cumulative_simpson#

scipy.integrate.cumulative_simpson(y, *, x=None, dx=1.0, axis=-1, initial=None)[source]#

使用复合辛普森 1/3 规则累积积分 y(x)。每个点的样本积分是通过假设每个点与其两个相邻点之间存在二次关系来计算的。

参数::
yarray_like

要积分的值。需要沿着 axis 至少有一个点。如果沿着 axis 提供了两个或更少的点,则辛普森积分不可行,结果将使用 cumulative_trapezoid 计算。

xarray_like, 可选

要积分的坐标。必须与 y 具有相同的形状,或者必须是 1D,其长度与 y 沿着 axis 相同。 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

y 沿着 axis 累积积分的结果。如果 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. 使用 MS Excel 和不规则间距的数据进行辛普森规则累积积分。数学科学与数学教育杂志。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()
../../_images/scipy-integrate-cumulative_simpson-1_00_00.png

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 多,它通常可以生成对子间隔上的基础积分的更准确估计。