Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用scipy.integrate.quad对复数进行积分_Python_Numpy_Scipy_Complex Numbers - Fatal编程技术网

Python 使用scipy.integrate.quad对复数进行积分

Python 使用scipy.integrate.quad对复数进行积分,python,numpy,scipy,complex-numbers,Python,Numpy,Scipy,Complex Numbers,我现在正在使用scipy.integrate.quad来成功地集成一些真实的被积函数。现在出现了一种情况,我需要积分一个复杂的被积函数。quad似乎无法像其他scipy.integrate例程那样实现这一点,因此我问:有没有任何方法可以使用scipy.integrate对复杂被积函数进行积分,而不必分离实部和虚部的积分 把它分成实部和虚部有什么不对scipy.integrate.quad要求使用集成函数return floats(也称为实数)作为其使用的算法 import scipy from

我现在正在使用scipy.integrate.quad来成功地集成一些真实的被积函数。现在出现了一种情况,我需要积分一个复杂的被积函数。quad似乎无法像其他scipy.integrate例程那样实现这一点,因此我问:有没有任何方法可以使用scipy.integrate对复杂被积函数进行积分,而不必分离实部和虚部的积分

把它分成实部和虚部有什么不对
scipy.integrate.quad
要求使用集成函数return floats(也称为实数)作为其使用的算法

import scipy
from scipy.integrate import quad

def complex_quadrature(func, a, b, **kwargs):
    def real_func(x):
        return scipy.real(func(x))
    def imag_func(x):
        return scipy.imag(func(x))
    real_integral = quad(real_func, a, b, **kwargs)
    imag_integral = quad(imag_func, a, b, **kwargs)
    return (real_integral[0] + 1j*imag_integral[0], real_integral[1:], imag_integral[1:])
例如:

>>> complex_quadrature(lambda x: (scipy.exp(1j*x)), 0,scipy.pi/2)
((0.99999999999999989+0.99999999999999989j),
 (1.1102230246251564e-14,),
 (1.1102230246251564e-14,))
这就是你所期望的误差,exp(ix)的整数从0开始,pi/2是(1/i)(e^i pi/2-e^0)=-i(i-1)=1+i~(0.99999999999989+0.99999999999989j)

如果不是所有人都100%清楚的话,那么集成是一个线性函数,这意味着∫ {f(x)+kg(x)}dx=∫ f(x)dx+k∫ g(x)dx(其中k是相对于x的常数)。或者针对我们的具体情况∫ z(x)dx=∫ Re z(x)dx+i∫ imz(x)dx为z(x)=rez(x)+imz(x)

如果要在复杂平面中的路径(而不是沿实轴)或复杂平面中的区域上进行积分,则需要更复杂的算法

注意:Scipy.integrate不会直接处理复杂的集成。为什么?它在FORTRAN库中完成了繁重的工作,特别是其中明确要求函数/变量在执行“基于每个子区间内21点Gauss–Kronrod求积的全局自适应求积,通过Peter Wynn的epsilon算法加速”之前为实因此,除非您想尝试修改底层FORTRAN,使其能够处理复数,并将其编译到一个新的库中,否则将无法使其工作

如果你真的想在一次积分中使用复数的Gauss-Kronrod方法,请按照下面的方法(使用15-pt,7-pt规则)直接查看和实现。注意,我将函数记忆为重复对公共变量的公共调用(假设函数调用很慢,好像函数非常复杂)。此外,只执行7-pt和15-pt规则,因为我不想自己计算节点/权重,也不想计算wikipedia上列出的节点/权重,但得到测试用例的合理错误(~1e-14)

测试用例:

>>> quad(lambda x: scipy.exp(1j*x), 0,scipy.pi/2.0)
[(0.99999999999999711+0.99999999999999689j), 9.6120083407040365e-19]
我不相信这个错误估计——我从wiki上取了一些东西作为从[-1到1]集成时的推荐错误估计,这些值对我来说似乎不合理。例如,与真实值相比,上述误差为~5e-15而非~1e-19。我相信如果有人参考num食谱,你会得到更准确的估计。(可能必须乘以
(a-b)/2
,以获得某种功率或类似功率)


回想一下,python版本不如仅仅调用scipy的基于QUADPACK的集成两次准确。(如果需要的话,你可以改进一下。)

我意识到我参加聚会迟到了,但也许(我的一个项目)能帮上忙。这个

导入四边形
进口numpy
val,err=quadpy.quad(λx:numpy.exp(1j*x),0,1)
打印(val)
正确地给出

(0.8414709848078964+0.4596976941318605j)

非常感谢,非常完整的回答。“我必须调整它以适应我的问题,但它非常有用。”Jimbob博士回答得非常有用。两个问题,命令“real_interal[1:],imag_integral[1:]”产生了什么?当你定义“复正交(func,a,b,**kwargs)”时,**kwargs代表什么参数?谢谢。在python中的函数参数中,在参数前面加上
**
使其成为可以传递的其他可选命名参数的
dict
。请参见,这样您就可以调用带有可选参数的
复数正交
,以传递到
四元组
some_sliceable[1:://code>将可切片的第0个元素之后的所有内容切片。通常,它只包含估计的abs误差。但是如果你调用
complex\u quarture(f,a,b,full\u output=True)
你会得到额外的信息。谢谢你的回答,但是在我的例子中,积分花费了太多的时间,积分加倍,这会使情况变得更糟。有没有办法在一个步骤而不是两个步骤中简单地计算出实部和虚部?这只是复制了你的答案吗?
(0.8414709848078964+0.4596976941318605j)