Numpy: Tempos de execução extremamente longos em numpy.fft.fft (Trac # 1266)

Criado em 19 out. 2012  ·  19Comentários  ·  Fonte: numpy/numpy

_Tíquete original http://projects.scipy.org/numpy/ticket/1266 em 19/10/2009 pelo usuário trac koehler, atribuído a desconhecido._

Embora a documentação de numpy.fft.fft afirme que:
"Isso é mais eficiente para uma potência de dois. Isso também armazena um cache de memória de trabalho para diferentes tamanhos de fft's, então você poderia teoricamente ter problemas de memória se chamar isso muitas vezes com muitos ns diferentes." , Acho que pode ser importante relatar essa estranheza no tempo de execução do fft.
Dependendo do comprimento do array, o tempo de execução fft varia muito:

[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

Comentários muito úteis

Isso deve ser corrigido em 1.17 numpy.

Todos 19 comentários

_ @ endolith escreveu em 20/11/2009

Relacionado: # 1177 http://projects.scipy.org/scipy/ticket/949

_ @ rgommers escreveu em

_ @ rgommers escreveu em

David C. implementou a transformação Bluestein se você precisar: https://github.com/cournape/numpy/tree/bluestein

Devo pousar no baú Numpy em breve.

Marco alterado para Unscheduled por @mwiebe em

neste primo é proposto um enchimento para pequenos primos
https://github.com/scipy/scipy/pull/3144
ter a função de obter um tamanho de preenchimento melhor pode ser um utilitário útil no numpys fftpack

Sim, em vez de m = 2 ** nextpow2(2 * n - 1) será mais rápido usar algo como a função next_regular

Eu também encontrei esse problema usando a função detect_equilibration de pymbar que chama repetidamente np.fft e np.ifft por meio da função de autocorrelação de modelos de estatísticas em muitos arrays cada vez mais curtos. Eu descobri o perfil do código, o que acabou me levando a este tópico. A única solução até agora é chamar explicitamente

 np.fft.fftpack._fft_cache.clear()

para ter certeza de que o requisito de memória não aumenta perigosamente. No entanto, esta não parece ser a solução ideal. Seria bom ter um kwarg como "memsafe = True" e / ou uma função para limpar manualmente o cache sem se referir explicitamente à variável global.

@juliantaylor O preenchimento não é aplicável a FFTs simples, correto? Apenas para convolução / correlação?

@rgommers O algoritmo Bluestein acelera o FFT para tamanhos primos, como feito em https://github.com/scipy/scipy/issues/4288 , mas requer pré-cálculo de chirps complexos e é mais eficiente quando você mantém o chirp na memória e reutilizá-lo repetidamente em blocos de dados. Portanto, não tenho certeza se isso é bom para numpy e talvez apenas adie para scipy.fftpack.czt para este aplicativo?

De qualquer forma, acho que isso pode ser fechado como uma duplicata de https://github.com/numpy/numpy/issues/1177 ? A menos que algo como o algoritmo de Rader seja melhor que o de Bluestein?

e o problema de @smcantab é diferente?

@endolith, isso foi há muito tempo :) mas sim, agora que olho novamente, parece um problema diferente. O problema que relatei ainda pode ser relevante e tive que implementar a solução alternativa que sugeri no pymbar para que funcionasse.

Para sua informação, encontrei alguém em uma audioconferência que me mostrou este exemplo. É fácil de reproduzir e extremo.

%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 de comprimento 1e6: 16 MILIsegundos

fft de comprimento 1e6 + 3: 1 MINUTO e 42 SEGUNDOS

Recurso, não um bug. FFTPACK só é "rápido" quando o tamanho é fatorado como produto dos números 2, 3, 4, 5. Há um desejo antigo de usar um algoritmo mais rápido para tamanhos primos grandes, mas ele não foi implementado. Observe que 100003 é primo.

Eu não chamaria de "recurso", mas é normal e não um bug. :)

https://github.com/scipy/scipy/issues/4288 tem o algoritmo de Bluestein, mas requer pré-cálculo de um chirp complexo, portanto, seria necessário fazer alguns testes para ver em quais tamanhos primos vale a pena.

Interessante. A principal coisa que sei é que a implementação padrão do fft para Julia e Matlab não tem esse comportamento. Estou curioso para saber o que a implementação de Julia faz para evitar esse comportamento.

Julia e Matlab ligam para FFTW, o que não podemos fazer por causa de sua licença.

Observe que existem ligações Python para FFTW; pyFFTW parece bastante atual. Se a velocidade do FFT for uma preocupação, provavelmente esse é o caminho a percorrer. O FFTPACK era uma boa implementação para sua época, mas o código e o hardware mudaram.

@charris Eu definitivamente aprecio a informação e isso é lamentável, mas faz sentido em relação à licença.

@standarddeviant Você também pode fazer um monkey-patch pyfftw sobre numpy / scipy para fazê-lo usar FFTW

Isso deve ser corrigido em 1.17 numpy.

obrigado @mreineck , fechando

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Kreol64 picture Kreol64  ·  3Comentários

thouis picture thouis  ·  4Comentários

keithbriggs picture keithbriggs  ·  3Comentários

Levstyle picture Levstyle  ·  3Comentários

dmvianna picture dmvianna  ·  4Comentários