Numerical Integration with Scipy integrate quad (and When to Use It)

When a Python calculation needs the area under a function, an antiderivative may not be useful. scipy.integrate.quad estimates the definite integral of a one-variable function and returns the estimate with an error estimate.

I’ll show how to pass a callable and its bounds, then how to read both returned values.

TL;DR: Use quad for a callable and two limits

scipy.integrate.quad estimates a one-variable definite integral and returns both the value and an estimate of its absolute error.

  • Pass the function itself, followed by its lower and upper limits.
  • Unpack the result as value, error when you need both numbers.
  • Use args for extra function parameters, or another integration routine for sampled data or multiple dimensions.

What is scipy.integrate.quad?

scipy.integrate.quad is SciPy’s adaptive numerical integrator for a callable of one variable over two bounds. Numerical integration estimates the area from function evaluations, so you can use it when an antiderivative is unavailable or not useful.

The function signature starts with quad(func, a, b): func receives a value x and returns the corresponding function value, while a and b mark the interval. The returned pair contains the integral estimate and an estimated absolute error. That second number describes the numerical calculation, not uncertainty in your model or measurements.

Under the hood, quad uses routines from QUADPACK and adjusts its evaluation across subintervals. It is therefore suited to a function that can be evaluated as needed, rather than a fixed table of measurements.

How to use scipy.integrate.quad step by step

Define a scalar-valued function, pass its limits to quad, then read the value and error separately. This example integrates 3x² from 0 to 2.

Step 1: Define the integrand

An integrand is the function being integrated. Pass a callable such as density, not a list of already sampled values.

from scipy.integrate import quad


def density(x, scale):
    return scale * x**2


value, abs_error = quad(density, 0, 2, args=(3,))
print(f"Integral: {value:.1f}")
print(f"Estimated absolute error: {abs_error:.2e}")

Run this saved example with python3 quad_parameter_demo.py. Its exact output is:

Integral: 8.0
Estimated absolute error: 8.88e-14
Terminal output from a SciPy quad example integrating 3x squared

The function receives x first and scale second. The args tuple supplies that second argument, and quad evaluates the function across the interval to estimate its integral.

Step 2: Choose the bounds

The second and third positional arguments are the lower and upper integration limits. The bounds can be infinite when the improper integral converges. For example, integrate exp(-x) over zero to infinity by passing numpy.inf as the upper bound.

from scipy.integrate import quad
import numpy as np

value, error = quad(lambda x: np.exp(-x), 0, np.inf)

For a finite interval, use bounds that surround the region where the integrand matters. A very wide interval can make a narrow feature harder for an adaptive method to detect.

Step 3: Read both return values

quad returns a two-item tuple: the estimated integral and an estimated absolute error. Unpack both as in the example, or take the first item of the returned tuple when later code needs only the integral estimate.

That distinction matters when using the result in another calculation. Assigning the whole return value to a variable keeps the pair, so adding it directly to a scalar is not the same as using the integral alone. Tuple unpacking names both outputs and keeps the error estimate available for a check.

Keeping the error value is useful when checking whether the requested numerical accuracy fits the task. Compare it with the scale of the integral and the needs of the application. Do not mistake a small estimate for proof that the integrand, bounds, or model are correct.

What can go wrong with quad?

quad estimates an integral. It cannot make a divergent integral converge or guarantee accuracy for every function. Check that the integrand and bounds describe a convergent problem, then inspect the error estimate and the function’s behavior.

The epsabs and epsrel options set absolute and relative accuracy targets. The documented target is the larger of epsabs and epsrel multiplied by the magnitude of the integral. Absolute tolerance matters when the integral is near zero, while relative tolerance scales with its size.

These options guide the algorithm, but they do not guarantee accuracy for an arbitrary integrand.

If a finite interval contains a known discontinuity or singular point, pass its location through points. This option is for finite bounds and cannot be combined with weighted integration. Splitting the interval into separate integrals can also make a difficult region explicit.

A function that returns an array is a different task from integrating one scalar function. Use quad_vec for vector-valued output. For a double or higher-dimensional integral, look at dblquad or nquad.

If you already have observations at sample points, use sampled-data methods such as scipy.integrate.trapezoid or scipy.integrate.simpson. Those routines use known values and x-coordinates instead of repeatedly calling a function to obtain values.

When you get an error about a callable, check that the first argument is a function such as density, not density(x) or an array of evaluated values. Calling density(x) passes its returned number to quad, which is not the function quad needs to evaluate across the interval.

For the extra-parameter example, args=(3,) is a one-item tuple. The comma matters in Python because parentheses alone do not create a tuple. With two parameters, pass both in order and define the callable to accept x first, then each extra value.

The parameterized example returned an integral estimate of 8.0 and an error estimate of 8.88e-14, matching the exact integral of 3x² over the stated bounds. That comparison checks this example, but an error estimate cannot validate an unfamiliar integrand.

For infinite bounds, quad transforms the interval before evaluating the function. The integral still has to converge, and the function must be defined at the points the routine evaluates. If the result changes sharply when you choose tighter finite bounds or split the range, investigate where the important contribution occurs rather than trusting the first estimate.

When more diagnostics are needed, full_output returns an information dictionary along with the result and error. It can expose function-evaluation and subdivision information, which helps investigate difficult calculations.

Conclusion: Read both values from quad

Use scipy.integrate.quad when the input is a scalar-valued function of one variable and the bounds define the integral you need. Keep the returned error estimate beside the value, and choose a different routine when the input is sampled data or the problem has multiple dimensions.

For parameter details and algorithm limits, see the SciPy quad reference and its integration tutorial. The AskPython scipy.integrate guide covers the wider integration module.

Frequently asked questions

These answers clarify the return value and input expected by quad.

How do I get a float from scipy.integrate.quad?

Unpack the returned tuple as value, error = quad(func, a, b), or use quad(func, a, b)[0] when you need only the integral estimate.

Does quad accept sampled values in an array?

No. quad expects a callable that evaluates the integrand for a scalar x. For values already sampled at points, use a sampled-data method such as scipy.integrate.trapezoid or scipy.integrate.simpson.

Can scipy.integrate.quad use infinite limits?

Yes. Use numpy.inf or -numpy.inf for an infinite endpoint when the improper integral converges.

Ninad
Ninad

A Python and PHP developer turned writer out of passion. Over the last 6+ years, he has written for brands including DigitalOcean, DreamHost, Hostinger, and many others. When not working, you'll find him tinkering with open-source projects, vibe coding, or on a mountain trail, completely disconnected from tech.

Articles: 136