matlab이 숫자 통합과 Scipy를 처리하는 방식에 약간의 좌절이 있습니다. 아래 테스트 코드에서 다음과 같은 차이점이 있습니다.
- Matlab의 버전은 내 파이썬 버전 보다 평균 24 배 빠릅니다 !
- Matlab의 버전은 경고없이 정수를 계산할 수 있으며 파이썬은 반환합니다
nan+nanj
언급 된 두 가지 점과 관련하여 파이썬에서 동일한 성능을 얻으려면 어떻게해야합니까? 문서에 따르면 두 방법 모두 적분을 근사하기 위해 "전역 적응 구적법"을 사용해야합니다.
아래는 두 버전의 코드입니다 (파이썬은 복잡한 정수를 처리 할 수 있도록 정수 함수를 작성해야하지만 상당히 유사합니다).
파이썬
import numpy as np
from scipy import integrate
import time
def integral(integrand, a, b, arg):
def real_func(x,arg):
return np.real(integrand(x,arg))
def imag_func(x,arg):
return np.imag(integrand(x,arg))
real_integral = integrate.quad(real_func, a, b, args=(arg))
imag_integral = integrate.quad(imag_func, a, b, args=(arg))
return real_integral[0] + 1j*imag_integral[0]
vintegral = np.vectorize(integral)
def f_integrand(s, omega):
sigma = np.pi/(np.pi+2)
xs = np.exp(-np.pi*s/(2*sigma))
x1 = -2*sigma/np.pi*(np.log(xs/(1+np.sqrt(1-xs**2)))+np.sqrt(1-xs**2))
x2 = 1-2*sigma/np.pi*(1-xs)
zeta = x2+x1*1j
Vc = 1/(2*sigma)
theta = -1*np.arcsin(np.exp(-np.pi/(2.0*sigma)*s))
t1 = 1/np.sqrt(1+np.tan(theta)**2)
t2 = -1/np.sqrt(1+1/np.tan(theta)**2)
return np.real((t1-1j*t2)/np.sqrt(zeta**2-1))*np.exp(1j*omega*s/Vc);
t0 = time.time()
omega = 10
result = integral(f_integrand, 0, np.inf, omega)
print time.time()-t0
print result
MATLAB
function [ out ] = f_integrand( s, omega )
sigma = pi/(pi+2);
xs = exp(-pi.*s./(2*sigma));
x1 = -2*sigma./pi.*(log(xs./(1+sqrt(1-xs.^2)))+sqrt(1-xs.^2));
x2 = 1-2*sigma./pi.*(1-xs);
zeta = x2+x1*1j;
Vc = 1/(2*sigma);
theta = -1*asin(exp(-pi./(2.0.*sigma).*s));
t1 = 1./sqrt(1+tan(theta).^2);
t2 = -1./sqrt(1+1./tan(theta).^2);
out = real((t1-1j.*t2)./sqrt(zeta.^2-1)).*exp(1j.*omega.*s./Vc);
end
t=cputime;
omega = 10;
result = integral(@(s) f_integrand(s,omega),0,Inf)
time_taken = cputime-t
np.vectorize
). 전체 배열에서 한 번에 계산을 시도하십시오. 그것은 불가능하지만, numba 또는 Cython을 살펴보십시오. 그러나 후자가 필요하지 않기를 바랍니다.