繁体   English   中英

为什么不使用 Scipy 的 FFT 代码结果与 Scipy FFT 不相似?

[英]Why is the result in FFT code without using Scipy not similar to Scipy FFT?

下面的 FFT 代码没有给出类似于scipy库的 scipy 库的结果。 但我不知道这段代码有什么问题。

import numpy as np
import matplotlib.pyplot as plt
#from scipy.fftpack import fft

def omega(p, q):
   return np.exp((-2j * np.pi * p) / q)

def fft(x):
   N = len(x)
   if N <= 1: return x
   even = fft(x[0::2])
   odd = fft(x[1::2])
   combined = [0] * N
   for k in range(N//2):
     combined[k] = even[k] + omega(k,N) * odd[k]
     combined[k + N//2] = even[k] - omega(k,N) * odd[k]
   return combined

 N = 600
 T = 1.0 / 800.0
 x = np.linspace(0, N*T, N)
 #y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
 y = np.sin(50.0 * 2.0*np.pi*x)
 xf = np.linspace(0.0, 1.0/(2.0*T), N//2)
 yf = fft(y)
 yfa = 2.0/N * np.abs(yf[0:N//2])
 plt.plot(xf, yfa)
 plt.show()

这给出了:

FFT 图

以上所有评论,舍入错误和实现正确性,都是正确的,但您错过了重要的事情...... FFT Cooley 和 Tukey 原始算法仅在样本数N是 2 的幂时才有效。您确实注意到

N600

np.allclose(yfa,yfa_sp)
>>> False

对于您当前的输入N = 600 ,您的 output 和 numpy/scipy 之间的差异很大。 但是现在,让我们使用 2 的幂,在这种情况下N = 2**9 = 512 ,它给出

np.allclose(yfa,yfa_sp)
>>> True

太好了,这次的输出是相同的,并且可以验证输入信号y的 2 的其他幂(除了奈奎斯特标准)大小。 对于深入的解释,您可以阅读这个问题的已接受答案,以了解为什么 numpy/scipy fft 函数可能允许所有N (当N是 2 的幂时效率最高,而当N是素数时效率最低)而不是仅仅处理这个你应该有的错误,比如

if np.log2(N) % 1 > 0:
    raise ValueError('size of input y must be a power of 2') 

正如评论中所建议的,如果信号的大小不能那么容易地修改,那么对于这种采样问题,零填充绝对是 go 的方法。

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM