Vergleichsweise langsame Python Numpy 3D Fourier Transformation

Für meine Arbeit muss ich diskrete Fourier-Transformationen (DFTs) für große Bilder durchführen. Im aktuellen Beispiel benötige ich eine 3D-FT für ein Bild von 1921 x 512 x 512 (zusammen mit 2D-FFTs von 512 x 512 Bildern). Im Moment benutze ich das Numpy-Paket und die zugehörige Funktion np.fft.fftn (). Das folgende Code-Snippet zeigt beispielhaft die 2D- und 3D-FFT-Zeiten in einem gleichgroßen / etwas kleineren 2D / 3D-Gitter, das durch Zufallszahlen generiert wurde:

import sys
import numpy as np
import time

tas = time.time()
a = np.random.rand(512, 512)
tab = time.time()
b = np.random.rand(100, 512, 512)

tbfa = time.time()

fa = np.fft.fft2(a)
tfafb = time.time()
fb = np.fft.fftn(b)
tfbe = time.time()

print "initializing 512 x 512 grid:", tab - tas
print "initializing 100 x 512 x 512 grid:", tbfa - tab
print "2D FFT on 512 x 512 grid:", tfafb - tbfa
print "3D FFT on 100 x 512 x 512 grid:", tfbe - tfafb

Ausgabe

initializing 512 x 512 grid: 0.00305700302124
initializing 100 x 512 x 512 grid: 0.301637887955
2D FFT on 512 x 512 grid: 0.0122730731964
3D FFT on 100 x 512 x 512 grid: 3.88418793678

Das Problem, das ich habe, ist, dass ich diesen Prozess ziemlich oft brauche, daher sollte die pro Bild aufgewendete Zeit kurz sein. Beim Testen auf meinem eigenen Computer (Laptop im mittleren Segment, 2 GB RAM für virtuelle Maschine (-> daher kleineres Testraster)) dauert die 3D-FFT ~ 5 s (Größenordnung). Bei der Arbeit sind die Maschinen jetzt viel besser, Cluster- / Grid-Architektur-Systeme und FFTs sind viel schneller. In beiden Fällen werden die 2D-Bilder quasi sofort beendet.

Allerdings mit 1921x512x512, np.fft.fftn () dauert ~ 5 min. Da die Implementierung von scipy vermutlich nicht viel schneller ist und ich davon ausgehe, dass MATLAB-FFTs mit Gittern gleicher Größe innerhalb von ~ 5 Sekunden enden, ist meine Frage, ob es eine Methode gibt, um den Prozess auf oder fast auf MATLAB-Zeiten zu beschleunigen. Mein Wissen über FFTs ist begrenzt, aber anscheinend verwendet MATLAB den FFTW-Algorithmus, was Python nicht tut. Gibt es eine vernünftige Chance, dass ich mit einem pyFFTW-Paket ähnliche Zeiten bekomme? Auch 1921 scheint eine unglückliche Wahl zu sein, da es nur 2 Primfaktoren gibt (17, 113), also nehme ich an, dass dies auch eine Rolle spielt. Andererseits ist 512 eine gut geeignete Zweierpotenz. Sind MATLAB-ähnliche Zeiten nach Möglichkeit auch ohne Auffüllen mit Nullen auf 2048 erreichbar?

Ich frage, weil ich häufig FFTs verwenden muss (in einem Ausmaß, in dem solche Unterschiede von großem Einfluss sind!) Und falls es keine Möglichkeit gibt, die Rechenzeiten in Python zu verkürzen, müsste ich auf wechseln andere, schnellere Implementierungen.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage