Python中的复杂集成

Python中的复杂集成,python,matlab,function,numpy,scipy,Python,Matlab,Function,Numpy,Scipy,有一个MATLAB函数可以计算复杂的积分,或者至少是具有极点和奇点的函数。在Python中,有一个通用的scipy.integrate.quad,它便于沿实轴进行集成。是否有一种Python等价于MATLAB的quadgk?我所能找到的是另一个SO问题,它似乎不再适用于Python 3.4了。我不认为SciPy提供了与MATLAB的quadgk相当的功能,但是值得一提的是,您在中链接的代码可以在Python 3中工作,只需稍作修改: import scipy from scipy import

有一个MATLAB函数可以计算复杂的积分,或者至少是具有极点和奇点的函数。在Python中,有一个通用的
scipy.integrate.quad
,它便于沿实轴进行集成。是否有一种Python等价于MATLAB的
quadgk
?我所能找到的是另一个SO问题,它似乎不再适用于Python 3.4了。

我不认为SciPy提供了与MATLAB的
quadgk
相当的功能,但是值得一提的是,您在中链接的代码可以在Python 3中工作,只需稍作修改:

import scipy
from scipy import array

def quad_routine(func, a, b, x_list, w_list):
    c_1 = (b-a)/2.0
    c_2 = (b+a)/2.0
    eval_points = map(lambda x: c_1*x+c_2, x_list)
    func_evals = list(map(func, eval_points))    # Python 3: make a list here
    return c_1 * sum(array(func_evals) * array(w_list))

def quad_gauss_7(func, a, b):
    x_gauss = [-0.949107912342759, -0.741531185599394, -0.405845151377397, 0, 0.405845151377397, 0.741531185599394, 0.949107912342759]
    w_gauss = array([0.129484966168870, 0.279705391489277, 0.381830050505119, 0.417959183673469, 0.381830050505119, 0.279705391489277,0.129484966168870])
    return quad_routine(func,a,b,x_gauss, w_gauss)

def quad_kronrod_15(func, a, b):
    x_kr = [-0.991455371120813,-0.949107912342759, -0.864864423359769, -0.741531185599394, -0.586087235467691,-0.405845151377397, -0.207784955007898, 0.0, 0.207784955007898,0.405845151377397, 0.586087235467691, 0.741531185599394, 0.864864423359769, 0.949107912342759, 0.991455371120813]
    w_kr = [0.022935322010529, 0.063092092629979, 0.104790010322250, 0.140653259715525, 0.169004726639267, 0.190350578064785, 0.204432940075298, 0.209482141084728, 0.204432940075298, 0.190350578064785, 0.169004726639267, 0.140653259715525,  0.104790010322250, 0.063092092629979, 0.022935322010529]
    return quad_routine(func,a,b,x_kr, w_kr)

class Memoize:                     # Python 3: no need to inherit from object
    def __init__(self, func):
        self.func = func
        self.eval_points = {}
    def __call__(self, *args):
        if args not in self.eval_points:
            self.eval_points[args] = self.func(*args)
        return self.eval_points[args]

def quad(func,a,b):
    ''' Output is the 15 point estimate; and the estimated error '''
    func = Memoize(func) #  Memoize function to skip repeated function calls.
    g7 = quad_gauss_7(func,a,b)
    k15 = quad_kronrod_15(func,a,b)
    # I don't have much faith in this error estimate taken from wikipedia
    # without incorporating how it should scale with changing limits
    return [k15, (200*scipy.absolute(g7-k15))**1.5]
比如说,

print(quad(lambda x: scipy.exp(1j*x), 0,scipy.pi/2.0))
[(0.99999999999999711+0.99999999999999689j), 9.6120083407040365e-19]

我建议你强调你需要一个复杂的轮廓。对于真实轮廓,您仍然可以使用
scipy.integrate.quad
分别计算实部和虚部。如果所有其他方法都失败了,您仍然可以手动完成:定义一个前端函数,该函数为两个复数极限定义线性路径
a1+i*a2
b1+i*b2
,在它们之间有一个实参数,并对得到的实部和虚部使用
quad
。。。我承认这远远不够漂亮,我希望有一个更简单、现成的解决方案:)我认为问题在于复杂的轮廓,比如从
-I
I
的积分。这个解决方案也适用于这种情况吗?如果我的积分极限达到无穷大,比如
print(quadgk(lambda x:scipy.exp(1j*x),-np.inf,0))
?然后我得到
[(nan+nan*j),nan]