I have this 2-dimensional integral with dependent limits. The function can be defined in Python as
def func(gamma, u2, u3):
return (1-1/(1+gamma-u3-u2))*(1/(
Here is a simpler method using scipy.integrate.dblquad instead of nquad
:
Return the double (definite) integral of func(y, x) from x = a..b and y = gfun(x)..hfun(x).
from scipy.integrate import dblquad
def func(u2, u3, gamma):
return (1-1/(1+gamma-u3-u2))*(1/(1+u2)**2)*(1/(1+u3)**2)
gamma = 10
def gfun(u3):
return 0
def hfun(u3):
return gamma-u3
dblquad(func, 0, gamma, gfun, hfun, args=(gamma,))
It seems that gfun
and hfun
do not accept the extra arguments, so gamma
has to be a global variable.
Using nquad
, after many trial and error:
from scipy.integrate import nquad
def func(u2, u3, gamma):
return (1-1/(1+gamma-u3-u2))*(1/(1+u2)**2)*(1/(1+u3)**2)
def range_u3(gamma):
return (0, gamma)
def range_u2(u3, gamma):
return (0, gamma-u3)
gamma = 10
nquad(func, [range_u2, range_u3], args=(gamma,) )
Useful quote from the source code of tplquad
:
# nquad will hand (y, x, t0, ...) to ranges0
# nquad will hand (x, t0, ...) to ranges1
And from the nquad
documentation, the order of the variables is reversed (same for dblquad
):
Integration is carried out in order. That is, integration over x0 is the innermost integral, and xn is the outermost
Generic case with k
nested integrations:
from scipy.integrate import nquad
import numpy as np
def func(*args):
gamma = args[-1]
var = np.array(args[:-1])
return (1-1/(1+gamma-np.sum(var)))*np.prod(((1+var)**-2))
def range_func(*args):
gamma = args[-1]
return (0, gamma-sum(args[:-1]))
gamma, k = 10, 2
nquad(func, [range_func]*k, args=(gamma,) )