【问题标题】:Why do FFT result show 2 non-zero amplitudes for a samples of single frequency?为什么 FFT 结果显示单个频率样本的 2 个非零幅度?
【发布时间】:2018-08-23 09:48:50
【问题描述】:

通过一个简单的 FFT 运行来学习操作,我创建了一个包含 100 个元素的 NumPy 数组,该数组中的正弦波只有一个周期。使用此代码:

...
n = 100
x = np.fromfunction(lambda a: np.sin(2 * np.pi * a / n), (n,), dtype=float)
res = np.fft.fft(x)
...

res 中的结果在 2 个不同的索引值处显示非零幅度:

idx           real         imag          abs
---     ----------   ----------   ----------
...
  1:             0      -50.000       50.000
...
 99:             0       50.000       50.000

我只希望在索引 1 处看到一个非零振幅。

为什么索引 1 和 99 的幅度都非零,我该如何从数学上理解这一点?

补充:也许高频实际上代表aliased频率,根据Nyquist rate,采样率太低。

【问题讨论】:

  • 请注意,SciPy 还具有 rfft 函数,用于处理实数(而不是复数)。
  • @DietrichEpp:谢谢,在scipy.fftpack.rfft 找到它。
  • 您可以将其视为混叠,但采样率并不太低……请记住,输入中只有一个周期的信号,因此奈奎斯特频率是 50 倍那。这里发生的是您的输入确实实际上包含两个不同复数频率的总和,一个在 f=+Fs/100,一个在 f=-Fs/ 100。复杂信号的虚部相互抵消,留下一个实值正弦波。混叠告诉我们,f=-Fs/100 处的信号将在 f=+Fs*99/100 处混叠,但这不是采样率高低的问题。
  • 当我说“复频率”时,我有点不准确。频率本身并不复杂,但复杂的傅立叶变换适用于不是正弦和余弦的信号,而是正弦和余弦的复值组合。由于复数有相位,我们可以认为正频率是相位随时间增加的信号,负频率是相位随时间减少的信号。 dsp.stackexchange.com/questions/4825/why-is-the-fft-mirrored
  • @DietrichEpp:再次感谢。您的 cmets 将我带到 The Scientist and Engineer's Guide to Digital Signal Processing, Chapter 12: The Fast Fourier Transform,它很好地描述了不同类型的实数与复数 FFT,以及有关实施的信息。

标签: python numpy fft


【解决方案1】:

np.fft.fft() 函数返回两侧 DFT 光谱。 您看到的是频率 w 和 -w 的峰值,其中 w 是正弦波的频率。

您可以通过运行np.fft.fftfreq 并绘制结果自行检查:

x = np.linspace(0, 2)
y = np.sin(2*np.pi*x)
Y = np.fft.fft(y)
freqs = np.fft.fftfreq(len(x), d=x[1]-x[0])

# Plot the results
fig, (ax1, ax2) = plt.subplots(2, 1)
ax1.plot(x, y)    
ax2.plot(freqs, np.abs(Y))

【讨论】:

  • 谢谢。我在之前添加了import matplotlib.pyplot as plt 和之后添加了plt.show() 以使其运行。
【解决方案2】:

傅里叶变换

其中Xk 是复数。虽然您的x 是实数,但结果是您得到X[N-m] = X[m]* 在您的情况下,N=100, m=1,因此,您有X[ 1 ] = X[99]

下面的链接解释了一切,

Why is the FFT “mirrored”?

在处理实数时,numpy提供了另一个函数numpy.fft.rfft

当为纯实数输入计算 DFT 时,输出是 Hermitian 对称的,即负频率项只是相应正频率项的复共轭,因此负频率项是多余的。此函数不计算负频率项,因此输出的变换轴长度为 n//2 + 1。

【讨论】:

  • 谢谢,N - 1 的复共轭值很好。
【解决方案3】:

标准的全 DFT 或 FFT 是 NxN 复数到复数的线性基变换,它返回其结果作为由复数元素组成的 N 元素向量,每个复数结果元素由实部和虚部组成。需要一个复杂的结果来表示每个频率分量的幅度和相位(因此不会有信息丢失)。虚部和实部的反正切表示每个频率分量的相位。

如果您使用严格实数输入(没有非零虚部)提供 FFT,那么您希望 FFT 结果表示严格实数信号。当 FFT 返回具有非零虚部的复数结果(如果相位非零时需要),这怎么可能?通过为每个信号返回两个分量,其中这两个分量的幅度相等,但它们的虚部相反,因此虚部抵消了。您仍然需要每个结果元素的虚部,以便测量相位。但看整个 FFT 结果,两个复数值中的虚部总和为零,因此表示严格的实数输入信号(没有虚部)。

因此,当给定严格的实数输入时,完整的 FFT 必须是复共轭镜像对称

因此,对于输入中的每个频率分量,您在 FFT 结果中看到(至少)两个相等的幅度值。当用非零虚部分量输入 FFT 复数输入时,这正确,这在许多物理方程和信号处理算法中很常见。

补充:为什么 FFT 必须返回一个复杂的结果,而不仅仅是幅度和相位角? FFT 代表 Fast 傅里叶变换。使 FFT 快速的一件事是它是一种线性变换,只需乘法和加法即可计算(加上一些巧妙的数据混洗)。实部和虚部可以仅用线性算术计算。而计算相位需要反正切(或 atan2()),这是一个慢得多的非线性超越算子。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 2019-09-05
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 2014-12-31
    相关资源
    最近更新 更多