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可呼叫物件 (callable)

評估要加總的項的函數。簽名必須是

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

其中 x 的每個元素都是有限實數,而 args 是一個元組,可能包含任意數量的陣列,這些陣列可與 x 進行廣播。

f 必須是逐元素函數:對於所有索引 i,每個元素 f(x)[i] 必須等於 f(x[i])。它不得修改陣列 xargs 中的陣列,並且當引數為 NaN 時,它必須傳回 NaN。

f 必須代表在 ab 之間所有實數上定義的平滑、正值、單峰函數 x

a, bfloat array_like

總和項的實數下限和上限。必須可廣播。 a 的每個元素都必須小於 b 中對應的元素。

stepfloat array_like

總和項之間的有限、正值實數步長。必須可與 ab 廣播。請注意,總和中包含的項數將為 floor((b - a) / step) + 1;相應地調整 b 以確保如果需要包含 f(b)

argstuple of array_like, optional

要傳遞給 f 的其他位置引數。必須是可與 abstep 廣播的陣列。如果要加總的可呼叫物件需要不可與 abstep 廣播的引數,請使用 f 包裝該可呼叫物件,以便 f 僅接受 x 和可廣播的 *args。請參閱範例。

logbool, default: False

設定為 True 表示 f 傳回項的對數,並且 atolrtol 表示為絕對誤差和相對誤差的對數。在這種情況下,結果物件將包含總和和誤差的對數。這對於數值下溢或溢位會導致不準確的被加數很有用。

maxtermsint, default: 2**20

直接求和要評估的最大項數。可能會執行額外的函數評估以進行輸入驗證和積分評估。

atol, rtolfloat, optional

絕對終止容差(預設值:0)和相對終止容差(預設值:eps**0.5,其中 eps 是結果 dtype 的精度)。如果 log 為 False,則必須是非負且有限的;如果 log 為 True,則必須表示為非負且有限數的對數。

傳回值:
res_RichResult

類似於 scipy.optimize.OptimizeResult 實例的物件,具有以下屬性。(描述的寫法就好像值將是純量;但是,如果 f 傳回陣列,則輸出將是相同形狀的陣列。)

successbool

True 當演算法成功終止時(狀態 0);否則為 False

statusint array

表示演算法結束狀態的整數。

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

  • -1 : abstep 的元素無效

  • -2 : 數值積分達到其迭代限制;總和可能發散。

  • -3 : 遇到非有限值。

  • -4 : 部分總和的最後一項的量級超過容差,因此誤差估計超過容差。考慮增加 maxterms 或放寬 tolerances。或者,可呼叫物件可能不是單峰的,或者求和的限制可能離函數最大值太遠。考慮增加 maxterms 或將總和分成幾部分。

sumfloat array

總和的估計值。

errorfloat array

絕對誤差的估計值,假設所有項都是非負的,函數被精確計算,並且直接求和精確到結果 dtype 的精度。

nfevint array

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]

Wikipedia. “積分判別法”. 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))