仅仅将其分为真正和富有想象力的部分有什么错误? <代码>scipy.integrate.quad要求使用的综合功能返回浮标(按实际数字计算)。
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,))
这是你预计会四舍五入的错误——从0, pi/2(1/i)(e^i pi/2 - e^0)=1+i ~(0.999999999999999999999999999999999999999999989j)。
而对于记录而言,如果人人都明白无误,则融合是一种线性功能,也就是说,∫{ f(x) + k(x) } dx = ∫ f(x) dx + k ∫ g(x) dx(k与x相比保持不变)。 或具体案件:∫ z(x) dx = ∫ Re z(x) dx + i ∫ Im z(x) dx as z(x) = Re z(x) + i Im z(x)。
如果你试图在复杂的飞机(除沿实际轴线以外)或复杂飞机区域采取一体化行动,那么你就需要有更复杂的算法。
注:设想方案不会直接处理复杂的融合问题。 为什么? http://en.wikipedia.org/wiki/QUADPACK"。 图书馆,特别是qagse.f 这明确要求履行职能/责任,然后在每一次间隔内根据21点“Gaus-Kronrod之四”进行“全球适应性修补”,Peter Wy s epsilon." 因此,除非你想尝试和修改《国家培训论坛》的基本内容,以便处理复杂的数字,将其汇编成一个新的图书馆,否则你就没有工作。
If you really want to do the Gauss-Kronrod method with complex numbers in exactly one integration, look at wikipedias page and implement directly as done below (using 15-pt, 7-pt rule). Note, I memoize d function to repeat common calls to the common variables (assuming function calls are slow as if the function is very complex). Also only did 7-pt and 15-pt rule, since I didn t feel like calculating the nodes/weights myself and those were the ones listed on wikipedia, but getting reasonable errors for test cases (~1e-14)
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 = map(func, eval_points)
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(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]
试验:
>>> quad(lambda x: scipy.exp(1j*x), 0,scipy.pi/2.0)
[(0.99999999999999711+0.99999999999999689j), 9.6120083407040365e-19]
I don t trust the error estimate -- I took something from wiki for recommended error estimate when integrating from [-1 to 1] and the values don t seem reasonable to me. 例如,the error above compared with truth is ~5e-15 not ~1e-19. I m sure if someone consulted num recipes, you could get a more accurate estimate. (Probably have to multiple by (a-b)/2
to some power or something similar).
Recall, the python version is less accurate than just calling scipy s QUADPACK based integration twice. (You could improve upon it if desired).