当信号频率恰好落在 fft bin 上时,Numpy FFT 会给出意想不到的结果
Numpy FFT give unexpected result when signal frequency falls exactly on a fft bin
当信号的频率恰好落在 FFT bin 上时,幅度变为 0!
但是如果我稍微偏移信号频率,结果就可以了。
复制代码:
这里信号的频率是30
import numpy as np
import matplotlib.pyplot as plt
N = 1024
Freq = 30
t = np.arange(N)
x = np.sin(2*np.pi*Freq/N*t)
f = np.fft.fft(x)
plt.plot(t, x)
plt.plot(t, f)
我希望输出在第 30 个 bin 中有一个巨大的尖峰,但它是平坦的,如下图所示。
但是,如果只是稍微将频率更改为 30.1 以使其不落在确切的 bin 上,
import numpy as np
import matplotlib.pyplot as plt
N = 1024
Freq = 30.1
t = np.arange(N)
x = np.sin(2*np.pi*Freq/N*t)
f = np.fft.fft(x)
plt.plot(t, x)
plt.plot(t, f)
结果正确如下图:
为什么?这是一个 numpy FFT 实现问题吗?还是标准FFT算法的限制?
f 是复数,我应该使用 abs(f) 进行绘图。
我忘记了 :P
- 要得到功率谱,需要取傅里叶系数的大小。绘制傅立叶系数直接舍弃虚部,只绘制实部。
- 从技术上讲,x 和 f 不应绘制在同一 x 轴上,因为它们具有不同的含义。
import numpy as np
import matplotlib.pyplot as plt
T = 1 # Total signal duration (s)
N = 1024 # samples over signal duration
Freq = 30 # frequency: (Hz)
t = np.arange(N)/N*T # time array
df = 1.0/T # resolution of angular frequency
f = np.arange(N)*df
x = np.sin(2*np.pi*Freq*t)
xhat = np.fft.fft(x) # Fourier series of x
plt.plot(t, x)
plt.xlabel("t (s)")
plt.ylabel("x")
plt.savefig("fig1.png")
plt.cla()
plt.plot(f, np.abs(xhat))
plt.xlabel("f (Hz)")
plt.ylabel("|fft(x)|")
plt.savefig("fig2.png")
当信号的频率恰好落在 FFT bin 上时,幅度变为 0! 但是如果我稍微偏移信号频率,结果就可以了。
复制代码:
这里信号的频率是30
import numpy as np
import matplotlib.pyplot as plt
N = 1024
Freq = 30
t = np.arange(N)
x = np.sin(2*np.pi*Freq/N*t)
f = np.fft.fft(x)
plt.plot(t, x)
plt.plot(t, f)
我希望输出在第 30 个 bin 中有一个巨大的尖峰,但它是平坦的,如下图所示。
但是,如果只是稍微将频率更改为 30.1 以使其不落在确切的 bin 上,
import numpy as np
import matplotlib.pyplot as plt
N = 1024
Freq = 30.1
t = np.arange(N)
x = np.sin(2*np.pi*Freq/N*t)
f = np.fft.fft(x)
plt.plot(t, x)
plt.plot(t, f)
结果正确如下图:
为什么?这是一个 numpy FFT 实现问题吗?还是标准FFT算法的限制?
f 是复数,我应该使用 abs(f) 进行绘图。 我忘记了 :P
- 要得到功率谱,需要取傅里叶系数的大小。绘制傅立叶系数直接舍弃虚部,只绘制实部。
- 从技术上讲,x 和 f 不应绘制在同一 x 轴上,因为它们具有不同的含义。
import numpy as np
import matplotlib.pyplot as plt
T = 1 # Total signal duration (s)
N = 1024 # samples over signal duration
Freq = 30 # frequency: (Hz)
t = np.arange(N)/N*T # time array
df = 1.0/T # resolution of angular frequency
f = np.arange(N)*df
x = np.sin(2*np.pi*Freq*t)
xhat = np.fft.fft(x) # Fourier series of x
plt.plot(t, x)
plt.xlabel("t (s)")
plt.ylabel("x")
plt.savefig("fig1.png")
plt.cla()
plt.plot(f, np.abs(xhat))
plt.xlabel("f (Hz)")
plt.ylabel("|fft(x)|")
plt.savefig("fig2.png")