Как получить правильные значения фазы, используя numpy.fft - PullRequest
1 голос
/ 12 апреля 2019
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)

enter image description here

Я получаю правильные значения для частоты и амплитуды. Но, как видно из графика, значения фазы не верны. Как извлечь правильные значения для фазы из FFT? Что именно я смотрю на фазовом графике?

Я ожидаю около 3,14 и 3,14 / 2 для частот 20 и 40 соответственно.

1 Ответ

1 голос
/ 12 апреля 2019

Есть две проблемы с вычислением фазы:

  1. Ваш входной сигнал не является целым числом периодов. Если вы будете многократно повторять сигнал, вы увидите, что на самом деле у вас есть другой набор частотных компонентов, чем вы предполагаете, когда создаете сигнал (ДПФ может восприниматься как использование бесконечного повторения вашего сигнала в качестве входного сигнала). Это приводит к тому, что пики имеют некоторую ширину, а также немного сдвигает фазу.

    Эту проблему вы можете решить, создав окно своего окна или создав его таким образом, чтобы оно содержало целое число периодов. Последний:

    T = 3 * np.pi
    t = np.linspace(0, T, n, endpoint=False)
    
  2. На частотах, где нет сигнала (который после вышеуказанного исправления - все, кроме двух частот), фаза будет задана шумом. Вы можете установить фазу здесь на ноль:

    angs[amps < 1] = 0
    

Теперь ваш сюжет выглядит так:

plot

Фазы не такие, как вы ожидали, потому что синус имеет фазу - & pi; / 2. Повторите эксперимент с cos вместо sin, и вы получите фазы, которые ожидали.

...