Ich möchte wiederholt ein zweidimensionales komplexes Integral mit dblquad von scipy.integrate berechnen. Da die Anzahl der Auswertungen sehr hoch sein wird, möchte ich die Auswertungsgeschwindigkeit meines Codes erhöhen.Scipy: Beschleunigung der Berechnung eines komplexen 2D-Integrals
Dblquad scheint nicht in der Lage zu sein, komplexe Integrale zu behandeln. Somit habe ich den Komplex Integrand in eine reale aufzuspalten und Imaginärteil:
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 und lam sind Variablen defind im Voraus. Um das Integral über die Fläche eines Kreises mit dem Radius ra bewerten ich die folgenden Befehle verwenden:
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]
Nach dem Profiler die beiden Integra werden etwa 35000 mal bewertet. Die Gesamtberechnung dauert etwa eine Sekunde, was für die Anwendung, die mir in den Sinn kommt, zu lang ist.
Ich bin ein Anfänger zum wissenschaftlichen Rechnen mit Python und Scipy und würde mich über Kommentare freuen, die Wege zur Verbesserung der Auswertungsgeschwindigkeit aufzeigen. Gibt es Möglichkeiten, die Befehle in den Funktionen integrand_real und integrand_complex neu zu schreiben, was zu signifikanten Geschwindigkeitsverbesserungen führen könnte?
Wäre es sinnvoll, diese Funktionen mit Tools wie Cython zu kompilieren? Wenn ja: Welches Tool passt am besten zu dieser Anwendung?
Ihre Funktion ist sogar in x. Durch einfaches Ändern der Integrationsgrenzen in '(0, ra)' wird die Rechenzeit um mehr als die Hälfte verkürzt. – Jaime
Hervorragender Kommentar Jaime! Ich folgte nur und bin jetzt bei 50% der ursprünglichen Berechnungszeit. Vielen Dank! – Olaf