#### Previous topic

scipy.integrate.tplquad

#### Next topic

scipy.integrate.fixed_quad

# scipy.integrate.nquad

`scipy.integrate.``nquad`(func, ranges, args=None, opts=None, full_output=False)

  Integration over multiple variables.

  Wraps `quad` to enable integration over multiple variables. Various options allow improved integration of discontinuous functions, as well as the use of weighted integration, and generally finer control of the integration process.

  > Parameters: | func : {callable, scipy.LowLevelCallable} The function to be integrated. Has arguments of `x0, ... xn`, `t0, tm`, where integration is carried out over `x0, ... xn`, which must be floats. Function signature should be `func(x0, x1, ..., xn, t0, t1, ..., tm)`. Integration is carried out in order. That is, integration over `x0` is the innermost integral, and `xn` is the outermost. If the user desires improved integration performance, then f may be a `scipy.LowLevelCallable` with one of the signatures:
  >     double func(int n, double *xx)
  >     double func(int n, double *xx, void *user_data)
  where `n` is the number of extra parameters and args is an array of doubles of the additional parameters, the `xx` array contains the coordinates. The `user_data` is the data contained in the `scipy.LowLevelCallable`. ranges : iterable object Each element of ranges may be either a sequence of 2 numbers, or else a callable that returns such a sequence. `ranges[0]` corresponds to integration over x0, and so on. If an element of ranges is a callable, then it will be called with all of the integration arguments available, as well as any parametric arguments. e.g. if `func = f(x0, x1, x2, t0, t1)`, then `ranges[0]` may be defined as either `(a, b)` or else as `(a, b) = range0(x1, x2, t0, t1)`. args : iterable object, optional Additional arguments `t0, ..., tn`, required by func, ranges, and `opts`. opts : iterable object or dict, optional Options to be passed to `quad`. May be empty, a dict, or a sequence of dicts or functions that return a dict. If empty, the default options from scipy.integrate.quad are used. If a dict, the same options are used for all levels of integraion. If a sequence, then each element of the sequence corresponds to a particular integration. e.g. opts[0] corresponds to integration over x0, and so on. If a callable, the signature must be the same as for `ranges`. The available options together with their default values are: epsabs = 1.49e-08 epsrel = 1.49e-08 limit = 50 points = None weight = None wvar = None wopts = None For more information on these options, see `quad` and `quad_explain`. full_output : bool, optional Partial implementation of `full_output` from scipy.integrate.quad. The number of integrand function evaluations `neval` can be obtained by setting `full_output=True` when calling nquad.
  Returns: | result : float The result of the integration. abserr : float The maximum of the estimates of the absolute error in the various integration results. out_dict : dict, optional A dict containing additional information on the integration.

  See also

  `quad`
    1-dimensional numerical integration

  `dblquad`, `tplquad`

  `fixed_quad`
    fixed-order Gaussian quadrature
  `quadrature`
    adaptive Gaussian quadrature

  Examples

      >>> from scipy import integrate
      >>> func = lambda x0,x1,x2,x3 : x0**2 + x1*x2 - x3**3 + np.sin(x0) + (
      ...                                 1 if (x0-.2*x3-.5-.25*x1>0) else 0)
      >>> points = [[lambda x1,x2,x3 : 0.2*x3 + 0.5 + 0.25*x1], [], [], []]
      >>> def opts0(*args, **kwargs):
      ...     return {'points':[0.2*args[2] + 0.5 + 0.25*args[0]]}
      >>> integrate.nquad(func, [[0,1], [-1,1], [.13,.8], [-.15,1]],
      ...                 opts=[opts0,{},{},{}], full_output=True)
      (1.5267454070738633, 2.9437360001402324e-14, {'neval': 388962})

      >>> scale = .1
      >>> def func2(x0, x1, x2, x3, t0, t1):
      ...     return x0*x1*x3**2 + np.sin(x2) + 1 + (1 if x0+t1*x1-t0>0 else 0)
      >>> def lim0(x1, x2, x3, t0, t1):
      ...     return [scale * (x1**2 + x2 + np.cos(x3)*t0*t1 + 1) - 1,
      ...             scale * (x1**2 + x2 + np.cos(x3)*t0*t1 + 1) + 1]
      >>> def lim1(x2, x3, t0, t1):
      ...     return [scale * (t0*x2 + t1*x3) - 1,
      ...             scale * (t0*x2 + t1*x3) + 1]
      >>> def lim2(x3, t0, t1):
      ...     return [scale * (x3 + t0**2*t1**3) - 1,
      ...             scale * (x3 + t0**2*t1**3) + 1]
      >>> def lim3(t0, t1):
      ...     return [scale * (t0+t1) - 1, scale * (t0+t1) + 1]
      >>> def opts0(x1, x2, x3, t0, t1):
      ...     return {'points' : [t0 - t1*x1]}
      >>> def opts1(x2, x3, t0, t1):
      ...     return {}
      >>> def opts2(x3, t0, t1):
      ...     return {}
      >>> def opts3(t0, t1):
      ...     return {}
      >>> integrate.nquad(func2, [lim0, lim1, lim2, lim3], args=(0,0),
      ...                 opts=[opts0, opts1, opts2, opts3])
      (25.066666666666666, 2.7829590483937256e-13)