Chcę wielokrotnie obliczyć dwuwymiarową całkę zespoloną za pomocą dblquad z scipy.integrate. Ponieważ liczba ocen będzie dość wysoka, chciałbym zwiększyć szybkość oceny mojego kodu.Scipy: Przyspieszanie obliczania całki zespolonej 2D
Dblquad wydaje się nie być w stanie obsłużyć złożonych elementów integrujących. Tak więc, mam podzielić złożony całki w prawdziwym i wyimaginowanym części:
def integrand_real(x, y):
R1=sqrt(x**2 + (y-y0)**2 + z**2)
R2=sqrt(x**2 + y**2 + zxp**2)
return real(exp(1j*k*(R1-R2)) * (-1j*z/lam/R2/R1**2) * (1+1j/k/R1))
def integrand_imag(x,y):
R1=sqrt(x**2 + (y-y0)**2 + z**2)
R2=sqrt(x**2 + y**2 + zxp**2)
return imag(exp(1j*k*(R1-R2)) * (-1j*z/lam/R2/R1**2) * (1+1j/k/R1))
y0, z, ZXP, k, i lam są zmiennymi defind wyprzedzeniem. Aby ocenić całki na obszarze okręgu o promieniu ra używam następujące polecenia:
from __future__ import division
from scipy.integrate import dblquad
from pylab import *
def ymax(x):
return sqrt(ra**2-x**2)
lam = 0.000532
zxp = 5.
z = 4.94
k = 2*pi/lam
ra = 1.0
res_real = dblquad(integrand_real, -ra, ra, lambda x: -ymax(x), lambda x: ymax(x))
res_imag = dblquad(integrand_imag, -ra, ra, lambda x: -ymax(x), lambda x: ymax(x))
res = res_real[0]+ 1j*res_imag[0]
Według profilera dwa podcałkowych oceniane są około 35.000 razy. Całkowite obliczenie zajmuje około jednej sekundy, co jest zbyt długie dla aplikacji, którą mam na myśli.
Jestem początkującym informatykiem naukowym z Python i Scipy i byłbym szczęśliwy z komentarzy wskazujących sposoby poprawy szybkości oceny. Czy istnieją sposoby przepisywania poleceń w funkcjach integrand_real i integrand_complex, które mogą prowadzić do znacznych ulepszeń prędkości?
Czy ma sens kompilowanie tych funkcji przy użyciu narzędzi takich jak Cython? Jeśli tak: które narzędzie najlepiej pasuje do tej aplikacji?
Twoja funkcja jest równa x. Po prostu zmiana granic integracji na '(0, ra)' skraca czas obliczeń o ponad połowę. – Jaime
Doskonały komentarz Jaime! Po prostu poszedłem za przykładem i mam teraz 50% pierwotnego czasu obliczeń. Dzięki! – Olaf