Numpy: Extrem lange Laufzeiten in numpy.fft.fft (Trac # 1266)

Erstellt am 19. Okt. 2012  ·  19Kommentare  ·  Quelle: numpy/numpy

_Ursprüngliches Ticket http://projects.scipy.org/numpy/ticket/1266 am 19.10.2009 vom Trac-Benutzer koehler, zugewiesen an unknown._

Obwohl die Dokumentation von numpy.fft.fft besagt, dass:
"Dies ist am effizientesten für eine Zweierpotenz. Hier wird auch ein Arbeitsspeicher für verschiedene FFT-Größen gespeichert, sodass theoretisch Speicherprobleme auftreten können, wenn Sie dies zu oft mit zu vielen verschiedenen Ns aufrufen." Ich denke, dass es wichtig sein kann, diese Seltsamkeit in der fft-Laufzeit zu melden.
Abhängig von der Array-Länge variiert die fft-Laufzeit sehr stark:

[ipython shell, from numpy import *]
In [1]: %time fft.fft(zeros(119516))
CPU times: user 22.83 s, sys: 0.39 s, total: 23.23 s
Wall time: 23.53 s

In [3]: %time fft.fft(zeros(119517))
CPU times: user 36.33 s, sys: 0.08 s, total: 36.40 s
Wall time: 36.51 s

In [5]: %time fft.fft(zeros(119518))
CPU times: user 4.88 s, sys: 0.08 s, total: 4.96 s
Wall time: 5.02 s

In [7]: %time fft.fft(zeros(119519))
CPU times: user 0.45 s, sys: 0.00 s, total: 0.45 s
Wall time: 0.45 s

In [9]: %time fft.fft(zeros(119515))
CPU times: user 0.07 s, sys: 0.00 s, total: 0.08 s
Wall time: 0.08 s

In [11]: %time fft.fft(zeros(119514))
CPU times: user 15.84 s, sys: 0.06 s, total: 15.90 s
Wall time: 15.95 s

In [13]: %time fft.fft(zeros(119513))
CPU times: user 272.75 s, sys: 1.03 s, total: 273.78 s
Wall time: 275.63 s
00 - Bug numpy.fft

Hilfreichster Kommentar

Dies sollte in numpy 1.17 behoben werden.

Alle 19 Kommentare

_ @ endolith schrieb am 2009-11-20_

Siehe auch: # 1177 http://projects.scipy.org/scipy/ticket/949

_ @ rgommers schrieb am 2011-03-01_

_ @ rgommers schrieb am 2011-03-01_

David C. hat die Bluestein-Transformation bei Bedarf implementiert: https://github.com/cournape/numpy/tree/bluestein

Sollte hoffentlich bald in Numpy Kofferraum landen.

Der Meilenstein wurde von @mwiebe am Unscheduled geändert

In diesem Pr wird eine Polsterung auf kleine Primzahlen vorgeschlagen
https://github.com/scipy/scipy/pull/3144
Die Funktion, eine bessere Polstergröße zu erhalten, könnte ein nützliches Dienstprogramm in numpys fftpack sein

Ja, anstelle von m = 2 ** nextpow2(2 * n - 1) es schneller, so etwas wie die Funktion next_regular verwenden

Ich bin auch auf dieses Problem gestoßen, indem ich die Funktion die Autokorrelationsfunktion von statsmodels auf vielen immer kürzeren Arrays

 np.fft.fftpack._fft_cache.clear()

um sicherzustellen, dass der Speicherbedarf nicht gefährlich wächst. Dies scheint jedoch nicht die ideale Lösung zu sein. Es wäre schön, entweder ein kwarg wie "memsafe = True" und / oder eine Funktion zum manuellen Löschen des Caches zu haben, ohne explizit auf die globale Variable zu verweisen.

@ juliantaylor Padding gilt nicht für einfache FFTs, richtig? Nur zur Faltung / Korrelation?

@rgommers Der Bluestein-Algorithmus beschleunigt die FFT für https://github.com/scipy/scipy/issues/4288 beschrieben , erfordert jedoch eine Vorberechnung komplexer Chirps und ist am effizientesten, wenn Sie die beibehalten Zwitschern Sie im Speicher und verwenden Sie ihn wiederholt für Datenblöcke. Ich bin mir also nicht sicher, ob dies für numpy gut ist und schiebe es für diese Anwendung möglicherweise einfach auf scipy.fftpack.czt zurück?

Wie auch immer, ich denke, dies kann als Duplikat von https://github.com/numpy/numpy/issues/1177 geschlossen werden ? Es sei denn, etwas anderes wie Raders Algorithmus ist besser als der von Bluestein?

und @smcantabs Problem ist anders?

@endolith das ist lange her :) aber ja, jetzt, wo ich es mir noch einmal

Zu Ihrer Information, ich habe jemanden auf einer Audiokonferenz getroffen, der mir dieses Beispiel gezeigt hat. Es ist leicht zu reproduzieren und extrem.

%time np.fft.fft( np.random.randn(100000) )
Wall time: 16 ms
Out[16]: 
array([ 196.58599022  +0.j        ,  -88.38483360 +89.2507627j ,
       -166.72250316+339.27161306j, ...,   12.22959535 -64.01621313j,
       -166.72250316-339.27161306j,  -88.38483360 -89.2507627j ])

%time np.fft.fft( np.random.randn(100003) )
Wall time: 1min 42s
Out[17]: 
array([  13.36160617  +0.j        , -314.86472577-340.44686425j,
       -258.36716707-170.43805382j, ...,  -21.18014704+441.3618185j ,
       -258.36716707+170.43805382j, -314.86472577+340.44686425j])

fft der Länge 1e6: 16 MILLIseconds

fft der Länge 1e6 + 3: 1 MINUTE und 42 SEKUNDEN

Feature, kein Bug. FFTPACK ist nur dann "schnell", wenn die Größe als Produkt der Zahlen 2, 3, 4, 5 gilt. Es besteht seit langem der Wunsch, einen schnelleren Algorithmus für große Primgrößen zu verwenden, dieser wurde jedoch nicht implementiert. Beachten Sie, dass 100003 eine Primzahl ist.

Ich würde es nicht als "Feature" bezeichnen, aber es ist normal und kein Fehler. :) :)

https://github.com/scipy/scipy/issues/4288 verfügt über den Bluestein-Algorithmus, erfordert jedoch eine Vorberechnung eines komplexen Chirps. Daher müssten einige Tests durchgeführt werden, um festzustellen, bei welchen Primgrößen es sich lohnt.

Interessant. Die Hauptsache, die ich weiß, ist, dass die Standard-FFT-Implementierung für Julia und Matlab dieses Verhalten nicht aufweist. Ich bin gespannt, was die Julia-Implementierung tut, um dieses Verhalten zu vermeiden.

Julia und Matlab rufen FFTW an, was wir aufgrund seiner Lizenz nicht tun können.

Beachten Sie, dass es Python-Bindungen für FFTW gibt. pyFFTW scheint ziemlich aktuell zu sein. Wenn die FFT-Geschwindigkeit ein Problem darstellt, ist dies wahrscheinlich der richtige Weg. FFTPACK war eine gute Implementierung für seine Zeit, aber Code und Hardware haben sich weiterentwickelt.

@charris Ich schätze die Informationen auf jeden Fall und das ist bedauerlich, macht aber Sinn in Bezug auf die Lizenz.

Dies sollte in numpy 1.17 behoben werden.

danke @mreineck , schließend

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen