I'm trying to integrate a function of 3 variables f(x,y,z) over all space.
When I integrate over a small volume, I get roughly the right result. However, when I increase the volume of integration, python says that the integral is zero.
I'm fairly confident that the issue here is that the function f is only non-zero in a small region of space, and tplquad dosen't sample over this region enough when the integration volume is large. I found an answer to a similar problem in 1D at this link; scipy.integrate.quad gives wrong result on large ranges. The solution in 1D was to pass an argument 'points' to scipy.integrate.quad, and this helped quad focus on the interval where the integral was non-zero.
My question is; is there a similar argument to 'points' for tplquad? Or perhaps some other way I can instruct tplquad to focus on a particular region of space?
The method tplquad
is just a wrapper over nquad
which does not expose all of the options of the latter. Use nquad
, which supports passing points
to quad
via opts
parameter. A simple example, with the same points for all ranges:
import numpy as np
from scipy.integrate import nquad
f = lambda x, y, z: np.exp(-x**2-y**2-z**2)
nquad(f, [[-150, 90], [-150, 90], [-150, 90]])[0] # 2.260158041551299e-16, wrong
nquad(f, [[-150, 90], [-150, 90], [-150, 90]], opts={"points": [-5, 5]})[0] # 5.568327996820292, correct
In general, opts
can be a list of different options for different steps of multiple integration, and points
can differ between them. They can also depend on other variables, like limits of integration can; see the example in the documentation.