np.angle 返回的相位不准确

问题描述

  • 我正在生成 2 个正弦波,第一个的基频 = 50 Hz,振幅 = 10,相位 = 0,第二个的基频 = 100 Hz,振幅 = 5 和相位 = np.pi/6(其中是 30 度)。
  • 然后我将它们相加,并对相加的信号执行 FFT。
  • 我使用 np.abs()
  • 计算了 50 Hz 和 100 Hz 的信号幅度
  • 我分别计算了 50 Hz 和 100 Hz 的信号相位 使用 np.angle()
  • 这是我得到的结果
'magnitude_50 Hz': 9.997827675356993,'phase_50 HZ': -89.0677734968239,'magnitude_150 Hz': 4.990392258900833,'phase_150 HZ': -57.231981462145704,

返回的震级分别非常接近 10 和 5。但是相位不是0度和30度。

我也尝试了其他方法,如 math.atan2cmath.phase,它提供了类似的结果。

我想了解我的相位计算有什么问题。我的代码如下。

def sine_wave(amplitude1: Union[int,float],amplitude2: Union[int,phase1: float,phase2: float,duration: Union[int,fund_freq_1: int,fund_freq_2: int,samp_freq: int) -> dict:
  
  # generating the time domain signal

  t = np.linspace(0,duration,int(samp_freq * duration))
  wave1 = amplitude1 * np.sin((2 * np.pi * fund_freq_1 * t)+phase1)
  wave2 = amplitude2 * np.sin((2 * np.pi * fund_freq_2 * t)+phase2)
  combined_wave = np.add(wave1,wave2)
  N = combined_wave.size
  T = 1/samp_freq

  # DFT
  f = np.fft.fftfreq(N,1 / samp_freq)
  fft = np.fft.fft(combined_wave)

  index_one = np.where(np.isclose(f,fund_freq_1))
  magnitude_one = np.mean(np.abs(fft[index_one]) * (2 / N))
  phase_one = degrees(np.angle(fft[index_one]))
  # phase_one = atan2(fft[index_one].imag,fft[index_one].real)
  # phase_one = degrees(phase(fft[index_one]))

  index_two = np.where(np.isclose(f,fund_freq_2))
  magnitude_two = np.mean(np.abs(fft[index_two]) * (2 / N))
  phase_two = degrees(np.angle(fft[index_two]))
  # phase_two = atan2(fft[index_two].imag,fft[index_one].real)
  # phase_two = degrees(phase(fft[index_two]))

  return {'magnitude_{} Hz'.format(fund_freq_1): magnitude_one,'phase_{} HZ'.format(fund_freq_1): phase_one,'magnitude_{} Hz'.format(fund_freq_2): magnitude_two,'phase_{} HZ'.format(fund_freq_2): phase_two}

代码可以这样运行

sine_wave(amplitude1=10,amplitude2=5,phase1=0,phase2=np.pi/6,duration=0.1,fund_freq_1=50,fund_freq_2=150,samp_freq=10000)

解决方法

执行 FFT 后,复数值的相位对应于带有 余弦的相对相位。由于 cos(x)sin(x) 有 90 度相位差,因此您应该期望以相对于相应 {{1} 的 -90 度相位检测到您的 0 度相位 sin }} 以相同的频率。同样,您的 30 度相位 cos 应该以 -60 度的相位检测。您的结果值确实非常接近。

如果您希望获得参考 sin 信号的相位,那么您可以简单地将 sin 的结果加上 90 度:

np.angle