如何使用 numpy.fft 获得正确的相位值

How to get correct phase values using numpy.fft

import numpy as np 
import matplotlib.pyplot as plt 

n = 500
T = 10
dw = 2 * np.pi / T

t = np.linspace(0, T, n)
x = 5 * np.sin(20 * t + np.pi)  + 10 * np.sin( 40 * t + np.pi/2)

fftx = np.fft.rfft(x)
freq = np.fft.rfftfreq(n) * n * dw

amps = np.abs(fftx) * 2 /  n
angs = np.angle(fftx) 


_, ax = plt.subplots(3, 1)
ax[0].plot(t, x)
ax[1].plot(freq, amps)
ax[2].plot(freq, angs)

我得到了正确的频率和振幅值。但从图中可以看出,相位值不正确。如何从 fft 中提取正确的相位值?我到底在看相图中的什么?

我预计频率 20 和 40 分别约为 3.14 和 3.14/2。

计算相位有两个问题:

  1. 您的输入信号不是整数个周期。如果你重复复制信号,你会发现你实际上有一组不同的频率分量,而不是你在构建信号时假设的(DFT 可以认为是使用无限重复的信号作为输入)。这会导致峰有一些宽度,也会导致相位偏移一点。

    您可以通过对信号加窗或创建信号使其具有整数个周期来解决此问题。后者是:

    T = 3 * np.pi
    t = np.linspace(0, T, n, endpoint=False)
    
  2. 没有信号的频率(上面修复后除两个频率外的所有频率),相位将由噪声给出。您可以将此处的相位设置为零:

    angs[amps < 1] = 0
    

现在你的情节看起来像这样:

相位与您预期的不一样,因为正弦的相位为 -π/2。使用 cos 而不是 sin 重复实验,您会得到预期的阶段。