scijit.integrate.quad

scijit.integrate.quad(func, a, b, args=(), full_output=0, epsabs=1.49e-08, epsrel=1.49e-08, limit=50, points=None, weight=None, wvar=None, wopts=None, maxp1=50, limlst=50, complex_func=False)

Adaptive integration of func from a to b.

One name over seven QUADPACK entry points, chosen from the values of a and b, from points and from weight.

call

QUADPACK

quad(f, 0.0, 1.0)

dqags

quad(f, 0.0, np.inf)

dqagi

quad(f, 0.0, 1.0, points=p)

dqagp

weight='cos'/'sin', finite

dqawo

weight='cos'/'sin', b=inf

dqawf

weight='alg'

dqaws

weight='cauchy'

dqawc

func is a plain @njit function, called as func(x, *args).

Calls nest, to any depth. A quad inside another quad’s integrand is correct: on int_0^1 int_0^1 exp(-x y) dy dx, whose value is 0.796599599297053, the nested call returns 0.7965995992970532. Each wrapper saves the thread’s callback slot on entry and restores it on exit, which is what makes that work.

nquad() is that nesting with its depth taken from the length of ranges, and dblquad and tplquad are nquad at depth two and three.

Parameters:
func@njit function

The integrand. It is called as func(x, *args), so it takes one argument when args is empty and 1 + len(args) otherwise, and returns the integrand value.

a, bfloat

Interval endpoints. Either may be np.inf or -np.inf. b < a gives the negated integral and a == b gives (0.0, 0.0).

argstuple, optional

Extra parameters, handed to func after x. A value that is not a tuple is read as a one-item tuple, so args=None is one argument and not none. An entry is a real number or an array of real numbers. A scalar keeps its type, so an integer arrives as an integer; an array’s data arrives as float64 at its own rank and shape. Default ().

full_outputbool or int, optional

Return the diagnostics as a third value. Default 0. Inside @njit it must be a compile-time constant: it selects the number of return values.

epsabs, epsrelfloat, optional

Requested absolute and relative accuracy. Both default to 1.49e-8.

limitint, optional

Maximum number of subintervals. Default 50.

pointsfloat64 array or None, optional

Interior break points, where the integrand has a known singularity or kink. Sorted, deduplicated and filtered to a < p < b first, so unsorted input, duplicates, out-of-range values, the endpoints themselves and nan/inf all drop out. Only with finite limits: an infinite one raises ValueError. Inside @njit None against an array is a compile-time choice.

weightstr or None, optional

Weight function folded into the integrand, one of 'cos', 'sin', 'alg', 'alg-loga', 'alg-logb', 'alg-log', 'cauchy'. Case sensitive. Inside @njit it must be a string literal, since it selects which QUADPACK routine is called.

wvarfloat or 2-element sequence, optional

The weight’s parameter: omega for 'cos'/'sin', c for 'cauchy', (alpha, beta) for the 'alg' family. A value the weight does not take raises TypeError. For a wvar ARRAY under the 'alg' family the length is read when the call runs, so the message names the requirement and not the length received.

woptsoptional

Accepted and ignored. Its purpose is to hand back precomputed Chebyshev moments.

maxp1int, optional

Upper bound on the number of Chebyshev moment sets for 'cos'/'sin'. Default 50.

limlstint, optional

Upper bound on the number of cycles for 'cos'/'sin' with b = inf. Default 50.

complex_funcbool, optional

Integrate a complex-valued func, by integrating its real and its imaginary part separately and recombining. Default False. Inside @njit it must be a compile-time constant, and it cannot be combined there with full_output.

Returns:
yfloat or complex

The integral. Complex when complex_func is true.

abserrfloat or complex

Estimate of the absolute error.

infodictdict

Present only when full_output is true. The key set for the routine the call reached: neval, last, alist, blist, rlist, elist and iord on the five ordinary routes, pts, level and ndin beside them on the break-point route, nnlog, chebmo and momcom on the oscillatory one, and neval, lst, rslst, erlst and ierlst on the cos/sin route to infinity. An empty interval, a == b, carries the unweighted key set whatever the route. The arrays have length limit, and length limlst for the cycle arrays on the cos/sin route to infinity; only [:last], or [:lst] there, is meaningful. One key is additive: ier, QUADPACK’s exit code, 0 for success.

EVERY VALUE IS A 1-D float64 ARRAY. neval, last, lst and ier are length 1, so infodict['neval'] reads array([21.]) and the value itself is infodict['neval'][0]. chebmo is flat, of length 25 * maxp1; .reshape(25, maxp1) recovers a two-dimensional shape. The value types are described under Notes.

With complex_func the two runs arrive under 'real' and 'imag'.

Raises:
ValueError

What QUADPACK reports as an invalid input: a limit below 1; a maxp1 below 1 or a limlst below 3 on a route that reads them; more break points than limit, or break points outside the interval; alpha or beta below -1; a Cauchy wvar equal to a limit; an epsabs at or below 0 with too small an epsrel. Also break points with an infinite limit, a cos/sin weight over (-inf, inf), an alg or cauchy weight over an infinite interval, and an unrecognised weight.

TypeError

func given as an address rather than as a function, with an arity that args does not fit, or returning a complex value while complex_func is false.

An empty interval, a == b, returns before any of these are
checked. Whatever the integrand raises is propagated.
Warns:
IntegrationWarning

On a soft QUADPACK failure (ier in 1, 2, 3, 4, 5, 7) with full_output false, and on points given together with weight, which is ignored.

See also

scipy.integrate.quad

The scipy routine this mirrors.

Notes

Three arguments are compile-time constants inside @njit: full_output, weight and complex_func. A runtime value in one of those slots raises TypingError naming it.

IntegrationWarning is a different class object from scipy.integrate.IntegrationWarning, with the same name and base, so a filter naming scipy’s class does not select it. Filter on this package’s class or on UserWarning.

The infodict’s values. Every value is a 1-D float64 array, where scipy’s infodict holds an int under neval, last, lst and momcom, int32 arrays under iord, level, ndin, nnlog and ierlst, and a two-dimensional chebmo. Read a count as int(info['neval'][0]) and the moments as info['chebmo'].reshape(25, maxp1).

A func returning a complex value while complex_func is false raises TypeError. scipy raises the same for a Python complex and, for a numpy complex128, warns once per evaluation and integrates the real part.

With complex_func true and full_output false, an empty interval returns 0j, where scipy returns 0.0.

Every diagnostic array is zeroed past last, where scipy leaves the tail uninitialised.

On a nonzero ier the Fortran layer also prints a short line to standard output, which numba cannot suppress.

Examples

A plain @njit integrand, with its extra parameters in the args tuple:

>>> import numpy as np
>>> from numba import njit
>>> import scijit.integrate as si
>>> @njit
... def f(x, c, d):
...     return c * np.exp(-d * x * x)
>>> @njit
... def run():
...     return si.quad(f, 0.0, 1.0, (2.0, 1.0))
>>> run()
(1.4936482656248542, 1.658282695188145e-14)

full_output adds the diagnostics, and must be a constant:

>>> @njit
... def g(x):
...     return np.exp(-x * x)
>>> @njit
... def run_full():
...     v, e, info = si.quad(g, 0.0, 1.0, (), True)
...     return v, info['neval'][0], info['last'][0], info['ier'][0]
>>> run_full()
(0.7468241328124271, 21.0, 1.0, 0.0)

A complex integrand, with complex_func:

>>> @njit
... def h(x, w):
...     return np.exp(1j * w * x)
>>> @njit
... def run_cx():
...     return si.quad(h, 0.0, 1.0, (2.0,), complex_func=True)
>>> run_cx()
((0.45464871341284085+0.7080734182735712j), (6.045545055588785e-15+7.861194120923578e-15j))