使用scipy.fftpack.fft如何解释傅立叶变换的数值结果

时间:2019-02-14 13:23:16

标签: python scipy fft

正弦信号的解析傅里叶变换为purely imginary。但是,在数值计算离散傅里叶变换时,结果并非如此。

Tldr:查找此问题here的所有答案。

因此请考虑以下代码

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

f_s = 200 # Sampling rate = number of measurements per second in [Hz]
t = np.arange(0,10000, 1 / f_s)
N = len(t)
A = 4 # Amplitude of sinus signal 
x = A * np.sin(t)
X = fft(x)[1:N//2]
freqs = (fftfreq(len(x)) * f_s)[1:N//2]

fig, (ax1,ax2) = plt.subplots(2,1, sharex = True)
ax1.plot(freqs, X.real, label = "$\Re[X(\omega)]$")
ax1.plot(freqs, X.imag, label = "$\Im[X(\omega)]$")
ax1.set_title("Discrete Fourier Transform of $x(t) = A \cdot \sin(t)$")
ax1.legend()
ax1.grid(True)

ax2.plot(freqs, np.abs(X), label = "$|X(\omega)|$")
ax2.legend()
ax2.set_xlabel("Frequency $\omega$")
ax2.set_yscale("log")
ax2.grid(True, which = "both")
ax2.set_xlim(0.15,0.175)
plt.show()

figure

很明显,绝对值| X(w)|可以很好地近似分析结果。但是,函数X(w)的虚数值和实数值不同。关于SO的another question已经提到了这一事实,但没有解释原因。所以我只能使用绝对值和相位吗?

另一个问题是振幅与数值结果之间的关系。从数学上讲,它应该是| X(w)|曲线下的积分。除以归一化(据我所知,应归纳为N),即大约为

A_approx = np.sum(np.abs(X)) / N
print(f"Numerical value: {A_approx:.1f}, Correct value: {A:.1f}")
  

数值:13.5,正确值:4.0

似乎并非如此。有什么见解吗?想法?

没有帮助的相关问题是herehere

1 个答案:

答案 0 :(得分:2)

FFT不能产生预期的结果,因为它的长度是有限的,因此更类似于正弦波上的矩形窗口的傅立叶变换。该矩形窗口的长度和位置会影响FFT结果的相位和幅度。