Implementing numerical integration using scipy.integrate.nquad

后端 未结 1 682
栀梦
栀梦 2021-01-26 10:42

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/(         


        
相关标签:
1条回答
  • 2021-01-26 11:27

    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,) )
    
    0 讨论(0)
提交回复
热议问题