【问题标题】:Optimizing Fourier transformed signal length优化傅里叶变换信号长度
【发布时间】:2016-04-29 03:50:39
【问题描述】:

我最近在使用np.fft.fft 计算信号的傅立叶变换时偶然发现了一个有趣的问题。重现的问题是:

%timeit np.fft.fft(np.random.rand(59601))    
1 loops, best of 3: 1.34 s per loop

发现时间出乎意料的长。例如,让我们看看其他一些 fft,但信号稍长/稍短:

%timeit np.fft.fft(np.random.rand(59600))
100 loops, best of 3: 6.18 ms per loop

%timeit np.fft.fft(np.random.rand(59602))
10 loops, best of 3: 61.3 ms per loop

%timeit np.fft.fft(np.random.rand(59603))
10 loops, best of 3: 113 ms per loop

%timeit np.fft.fft(np.random.rand(59604))
1 loops, best of 3: 182 ms per loop

%timeit np.fft.fft(np.random.rand(59605))
100 loops, best of 3: 6.53 ms per loop

%timeit np.fft.fft(np.random.rand(59606))
1 loops, best of 3: 2.17 s per loop

%timeit np.fft.fft(np.random.rand(59607))
100 loops, best of 3: 8.14 ms per loop

我们可以观察到时间现在以毫秒为单位,除了np.random.rand(59606),它持续了 2.17 秒。

注意,numpy 文档指出:

FFT(快速傅里叶变换)是指通过在计算项中使用对称性来有效计算离散傅里叶变换 (DFT) 的一种方式。当 n 是 2 的幂时,对称性最高,因此对于这些大小,变换效率最高。

但是,这些向量的长度不是 2 的幂。当计算时间相当长时,有人可以解释如何避免/预测情况吗?

【问题讨论】:

  • 59601 是 3*19867,19867 是素数。见stackoverflow.com/questions/21161033/…
  • 另外,59606 是 2*29803,29803 是素数。对于非常慢的情况,请尝试 59611,它是素数。
  • 是的,就是这样。谢谢!

标签: python numpy scipy fft


【解决方案1】:

正如一些 cmets 所指出的,素因子分解允许您预测计算 FFT 的时间。下图显示了您的结果。备注对数刻度!

此图像是使用以下代码生成的:

import numpy as np
import matplotlib.pyplot as plt

def prime_factors(n):
    """Returns all the prime factors of a positive integer"""
    #from http://stackoverflow.com/questions/23287/largest-prime-factor-of-a-number/412942#412942
    factors = []
    d = 2
    while n > 1:
        while n % d == 0:
            factors.append(d)
            n /= d
        d = d + 1

    return factors


times = []
decomp = []
for i in range(59600, 59613):
    print(i)
    t= %timeit -o np.fft.fft(np.random.rand(i))
    times.append(t.best)
    decomp.append(max(prime_factors(i)))

plt.loglog(decomp, times, 'o')
plt.ylabel("best time")
plt.xlabel("largest prime in prime factor decomposition")
plt.title("FFT timings")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多