bundles / scipy 1.17.1 / scipy / integrate / _tanhsinh / nsum
function
scipy.integrate._tanhsinh:nsum
Signature
def nsum ( f , a , b , * , step = 1 , args = () , log = False , maxterms = 1048576 , tolerances = None ) Summary
Evaluate a convergent finite or infinite series.
Extended Summary
For finite a and b, this evaluates
f(a + np.arange(n)*step).sum()where n = int((b - a) / step) + 1, where f is smooth, positive, and unimodal. The number of terms in the sum may be very large or infinite, in which case a partial sum is evaluated directly and the remainder is approximated using integration.
Parameters
f: callableThe function that evaluates terms to be summed. The signature must be
f(x: ndarray, *args) -> ndarraywhere each element of
xis a finite real andargsis a tuple, which may contain an arbitrary number of arrays that are broadcastable withx.fmust be an elementwise function: each elementf(x)[i]must equalf(x[i])for all indicesi. It must not mutate the arrayxor the arrays inargs, and it must return NaN where the argument is NaN.fmust represent a smooth, positive, unimodal function ofxdefined at all reals betweenaandb.a, b: float array_likeReal lower and upper limits of summed terms. Must be broadcastable. Each element of
amust be less than the corresponding element inb.step: float array_likeFinite, positive, real step between summed terms. Must be broadcastable with
aandb. Note that the number of terms included in the sum will befloor((b - a) / step)+ 1; adjustbaccordingly to ensure thatf(b)is included if intended.args: tuple of array_like, optionalAdditional positional arguments to be passed to
f. Must be arrays broadcastable witha,b, andstep. If the callable to be summed requires arguments that are not broadcastable witha,b, andstep, wrap that callable withfsuch thatfaccepts onlyxand broadcastable*args. See Examples.log: bool, default: FalseSetting to True indicates that
freturns the log of the terms and that atol and rtol are expressed as the logs of the absolute and relative errors. In this case, the result object will contain the log of the sum and error. This is useful for summands for which numerical underflow or overflow would lead to inaccuracies.maxterms: int, default: 2**20The maximum number of terms to evaluate for direct summation. Additional function evaluations may be performed for input validation and integral evaluation.
atol, rtol: float, optionalAbsolute termination tolerance (default: 0) and relative termination tolerance (default:
eps**0.5, whereepsis the precision of the result dtype), respectively. Must be non-negative and finite iflogis False, and must be expressed as the log of a non-negative and finite number iflogis True.
Returns
res: _RichResultAn object similar to an instance of scipy.optimize.OptimizeResult with the following attributes. (The descriptions are written as though the values will be scalars; however, if
freturns an array, the outputs will be arrays of the same shape.)success
success
status
status
sum
sum
error
error
nfev
nfev
Notes
The method implemented for infinite summation is related to the integral test for convergence of an infinite series: assuming step size 1 for simplicity of exposition, the sum of a monotone decreasing function is bounded by
Let represent a, represent maxterms, represent atol, and represent rtol. The implementation first evaluates the integral as a lower bound of the infinite sum. Then, it seeks a value such that , if it exists; otherwise, let . Then the infinite sum is approximated as
and the reported error is plus the error estimate of numerical integration. Note that the integral approximations may require evaluation of the function at points besides those that appear in the sum, so f must be a continuous and monotonically decreasing function defined for all reals within the integration interval. However, due to the nature of the integral approximation, the shape of the function between points that appear in the sum has little effect. If there is not a natural extension of the function to all reals, consider using linear interpolation, which is easy to evaluate and preserves monotonicity.
The approach described above is generalized for non-unit step and finite b that is too large for direct evaluation of the sum, i.e. b - a + 1 > maxterms. It is further generalized to unimodal functions by directly summing terms surrounding the maximum. This strategy may fail:
If the left limit is finite and the maximum is far from it.
If the right limit is finite and the maximum is far from it.
If both limits are finite and the maximum is far from the origin.
In these cases, accuracy may be poor, and nsum may return status code 4.
Although the callable f must be non-negative and unimodal, nsum can be used to evaluate more general forms of series. For instance, to evaluate an alternating series, pass a callable that returns the difference between pairs of adjacent terms, and adjust step accordingly. See Examples.
Array API Standard Support
nsum has experimental support for Python Array API Standard compatible backends in addition to NumPy. Please consider testing these features by setting an environment variable SCIPY_ARRAY_API=1 and providing CuPy, PyTorch, JAX, or Dask arrays as array arguments. The following combinations of backend and device (or other capability) are supported.
==================== ==================== ==================== Library CPU GPU ==================== ==================== ==================== NumPy ✅ n/a CuPy n/a ✅ PyTorch ⛔ ⛔ JAX ⛔ ⛔ Dask ⛔ n/a ==================== ==================== ====================
See
dev-arrayapifor more information.
Examples
Compute the infinite sum of the reciprocals of squared integers.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 (res.sum - ref)/ref # true error res.nfev # number of points at which callable was evaluated✓
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)✓
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
✗See also
- mpmath.nsum
Aliases
-
scipy.integrate.nsum