scipy.integrate.

nsum#

scipy.integrate.nsum(f, a, b, *, step=1, args=(), log=False, maxterms=1048576, tolerances=None)[源代码]#

评估收敛的有限或无限级数。

对于有限的 ab,这会评估

f(a + np.arange(n)*step).sum()

其中 n = int((b - a) / step) + 1,其中 f 是平滑、正值且单峰的函数。求和中的项数可能非常大或无限,在这种情况下,直接评估部分和,并使用积分近似余数。

参数:
f可调用对象

用于评估要求和的项的函数。其签名必须是

f(x: ndarray, *args) -> ndarray

其中 x 的每个元素都是有限实数,args 是一个元组,可能包含任意数量的与 x 可广播的数组。

f 必须是一个元素级函数:对于所有索引 if(x)[i] 必须等于 f(x[i])。它不得修改数组 xargs 中的数组,并且当参数为 NaN 时必须返回 NaN。

f 必须表示一个在 ab 之间的所有实数上定义的平滑、正值、单峰函数。

a, b浮点数数组类型

求和项的实数下限和上限。必须可广播。 a 的每个元素必须小于 b 中的相应元素。

step浮点数数组类型

求和项之间有限、正、实数的步长。必须与 ab 可广播。请注意,求和中包含的项数将是 floor((b - a) / step) + 1;请相应调整 b,以确保如果预期,f(b) 会被包含在内。

args数组类型元组,可选

要传递给 f 的额外位置参数。必须是可与 abstep 广播的数组。如果要求和的可调用对象需要与 abstep 不可广播的参数,则将该可调用对象用 f 封装,使得 f 只接受 x 和可广播的 *args。参见示例。

log布尔值,默认值:False

设置为 True 表示 f 返回项的对数,并且 atolrtol 表示为绝对误差和相对误差的对数。在这种情况下,结果对象将包含和的对数和误差。这对于可能导致数值下溢或上溢不准确的求和项很有用。

maxterms整数,默认值:2**20

直接求和要评估的最大项数。可能会执行额外的函数评估以进行输入验证和积分评估。

atol, rtol浮点数,可选

绝对终止容差(默认值:0)和相对终止容差(默认值:eps**0.5,其中 eps 是结果数据类型的精度)。如果 log 为 False,则必须为非负且有限;如果 log 为 True,则必须表示为非负有限数的对数。

返回:
res_RichResult

一个类似于 scipy.optimize.OptimizeResult 实例的对象,具有以下属性。(描述假定值为标量;但是,如果 f 返回数组,则输出将是相同形状的数组。)

success布尔值

当算法成功终止时(状态 0)为 True;否则为 False

status整数数组

表示算法退出状态的整数。

  • 0 : 算法收敛到指定的容差。

  • -1 : abstep 的元素无效

  • -2 : 数值积分达到其迭代限制;求和可能发散。

  • -3 : 遇到非有限值。

  • -4 : 部分和的最后一项的幅度超过容差,因此误差估计超过容差。请考虑增加 maxterms 或放宽 tolerances。另外,可调用对象可能不是单峰的,或者求和的限制可能离函数最大值太远。请考虑增加 maxterms 或将求和分解为多个部分。

sum浮点数数组

和的估计值。

error浮点数数组

绝对误差的估计值,假设所有项都是非负的,函数计算精确,并且直接求和的精度与结果数据类型相同。

nfev整数数组

评估 f 的点的数量。

另请参阅

mpmath.nsum

注释

为无限求和实现的该方法与无限级数收敛的积分判别法有关:为简化说明,假设 step 大小为 1,单调递减函数的和受以下条件限制:

\[\int_u^\infty f(x) dx \leq \sum_{k=u}^\infty f(k) \leq \int_u^\infty f(x) dx + f(u)\]

\(a\) 表示 a\(n\) 表示 maxterms\(\epsilon_a\) 表示 atol\(\epsilon_r\) 表示 rtol。该实现首先评估积分 \(S_l=\int_a^\infty f(x) dx\) 作为无限和的下界。然后,它寻找一个值 \(c > a\),如果存在,使得 \(f(c) < \epsilon_a + S_l \epsilon_r\);否则,令 \(c = a + n\)。然后将无限和近似为

\[\sum_{k=a}^{c-1} f(k) + \int_c^\infty f(x) dx + f(c)/2\]

报告的误差是 \(f(c)/2\) 加上数值积分的误差估计。请注意,积分近似可能需要评估函数在求和中出现的点之外的点,因此 f 必须是定义在积分区间内所有实数上的连续单调递减函数。然而,由于积分近似的性质,函数在求和中出现的点之间的形状影响很小。如果没有将函数自然推广到所有实数的方法,请考虑使用线性插值,它易于评估且保留单调性。

上述方法针对非单位 step 和对于直接评估求和而言过大的有限 b 进行了推广,即 b - a + 1 > maxterms。通过直接求和最大值周围的项,它进一步推广到单峰函数。此策略可能失败

  • 如果左限是有限的且最大值远离它。

  • 如果右限是有限的且最大值远离它。

  • 如果两个限制都是有限的且最大值远离原点。

在这些情况下,准确性可能很差,并且 nsum 可能会返回状态码 4

尽管可调用对象 f 必须是非负且单峰的,但 nsum 可用于评估更一般的级数形式。例如,要评估交错级数,请传递一个返回相邻项对之间差异的可调用对象,并相应调整 step。参见示例。

参考文献

[1]

维基百科。“积分判别法。” https://en.wikipedia.org/wiki/Integral_test_for_convergence

示例

计算平方整数倒数的无限和。

>>> import numpy as np
>>> from scipy.integrate import nsum
>>> res = nsum(lambda k: 1/k**2, 1, np.inf)
>>> ref = np.pi**2/6  # true value
>>> res.error  # estimated error
np.float64(7.448762306416137e-09)
>>> (res.sum - ref)/ref  # true error
np.float64(-1.839871898894426e-13)
>>> res.nfev  # number of points at which callable was evaluated
np.int32(8561)

计算整数的 p 次幂倒数的无限和,其中 p 是一个数组。

>>> from scipy import special
>>> p = np.arange(3, 10)
>>> res = nsum(lambda k, p: 1/k**p, 1, np.inf, maxterms=1e3, args=(p,))
>>> ref = special.zeta(p, 1)
>>> np.allclose(res.sum, ref)
True

评估交错调和级数。

>>> res = nsum(lambda x: 1/x - 1/(x+1), 1, np.inf, step=2)
>>> res.sum, res.sum - np.log(2)  # result, difference vs analytical sum
(np.float64(0.6931471805598691), np.float64(-7.616129948928574e-14))