fft.fft() 的幅度和相位(角度)输出与设置的值不对应

Output of fft.fft() for magnitude and phase (angle) not corresponding the the values set up

我设置了一定幅度、频率和相位的正弦波,并尝试恢复幅度和相位:

import numpy as np
import matplotlib.pyplot as plt

N = 1000  # Sample points     
T = 1 / 800         # Spacing

t = np.linspace(0.0, N*T, N) # Time
frequency = np.fft.fftfreq(t.size, d=T) # Normalized Fourier frequencies in spectrum.

f0 = 25              # Frequency of the sampled wave
phi = np.pi/6       # Phase
A = 50              # Amplitude
s = A * np.sin(2 * np.pi * f0 * t - phi) # Signal

S = np.fft.fft(s)   # Unnormalized FFT

fig, [ax1,ax2] = plt.subplots(nrows=2, ncols=1, figsize=(10, 5))
ax1.plot(t,s,'.-', label='time signal')  
ax2.plot(freq[0:N//2], 2/N * np.abs(S[0:N//2]), '.', label='amplitude spectrum')

plt.show()

index, = np.where(np.isclose(frequency, f0, atol=1/(T*N))) # Getting the normalized frequency close to f0 in Hz)
magnitude = np.abs(S[index[0]]) # Magnitude
phase = np.angle(S[index[0]])   # Phase
print(magnitude)
print(phase)
phi
#21785.02149316858
#-1.2093259641890741
#0.5235987755982988

现在幅度应该是 50,而不是 21785,相位 pi/6=0.524,而不是 -1.2。

我是不是误解了输出,或者上面 link 中提到的 post 的答案?

  • 您需要通过以下两个更改之一将 fft 标准化为 1/N(我使用了第二个):
    S = np.fft.fft(s) --> S = 1/N*np.fft.fft(s)
    magnitude = np.abs(S[index[0]]) --> magnitude = 1/N*np.abs(S[index[0]])
  • 不要使用index, = np.where(np.isclose(frequency, f0, atol=1/(T*N))),fft 不准确,最大幅度可能 不是 f0,而是使用 np.argmax(np.abs(S)) 您的信号峰值非常接近 f0
  • np.angle 搞砸了(我认为它是 pi,pi/2 arctan 偏移量之一 事情)只需用 np.arctan(np.real(x)/np.imag(x))
  • 手动完成
  • 使用更多点(我使 N 更高)并使 T 更小以获得更高的准确性
  • 由于 DFT(离散傅立叶变换)是双面的,并且在负频率和正频率中都有峰值信号,因此正侧的峰值只会是实际幅度的一半。对于 fft,除了 f=0 之外,您需要将每个频率乘以 2 才能解决这个问题。我在 magnitude = np.abs(S[index])*2/N
  • 中乘以 2
N = 10000
T = 1/5000
...
index = np.argmax(np.abs(S))
magnitude = np.abs(S[index])*2/N
freq_max = frequency[index]
phase = np.arctan(np.imag(S[index])/np.real(S[index])) 
print(f"magnitude: {magnitude}, freq_max: {freq_max}, phase: {phase}") print(phi)

输出:magnitude: 49.996693276663564, freq_max: 25.0, phase: 0.5079341239733628