2016-10-01 3 views
3

Небольшая программа, которую я написал в октаве, не дает желаемого фазового спектра. График амплитуды идеален.Октава: неправильный фазовый спектр FFT

f = 200; 
fs = 1000; 
phase = pi/3; 
t = 0: 1/fs: 1; 
sig = sin((2*pi*f*t) + phase); 
sig_fft = fft(sig); 

sig_fft_phase = angle(sig_fft) * 180/pi; 

sig_fft_phase(201) 

sig_fft_phase(201) возвращается 5.998 (6 градусов), а не на 60 градусов. Что я делаю не так? Является ли мое ожидание неправильным?

+0

Это -> https://www.mathworks.com/matlabcentral/answers/1139#answer_1625 кажется, что ответ на такой же проблемой! –

ответ

4

В вашем примере, если вы создаете ось частоты: (извините, я не Октава здесь, так что Python будет делать-я уверен это то же самое в октаву):

faxis = (np.arange(0, t.size)/t.size) * fs 

вы увидите, что faxis[200] (индекс Python равен 0, что эквивалентно индексу Octave's 201): 199.80019980019981. Вы думаете, что просите фазу на частоте 200 Гц, но вы этого не сделаете, вы просите фазу 199,8 Гц.

(Это происходит потому, что ваш t вектор включает в себя 1,0-что один дополнительный образец немного уменьшает спектральный интервал! Я не думать ссылка @Sardar_Usama писал в своем комментарии является правильным, оно не имеет ничего общего с тем, что синусоида не заканчивается на полный цикле, так как этот подход должна работы с неполными циклами)

решения:. нулевая колодкой с 1001-длинный вектором sig до 2000 образцов. Затем с новой faxis частоты вектора, faxis[400] (индекс Октава четыреста первого в) соответствует ровно 200 Гц:

In [54]: sig_fft = fft.fft(sig, 2000); 

In [55]: faxis = np.arange(0, sig_fft.size)/sig_fft.size * fs 

In [56]: faxis[400] 
Out[56]: 200.0 

In [57]: np.angle(sig_fft[400]) * 180/np.pi 
Out[57]: -29.950454729683386 

Но о нет, что случилось? Это говорит о том, что угол составляет -30 °?

Хорошо, напомним, что Euler’s formula говорит, что sin(x) = (exp(i * x) - exp(-i * x))/2i. То, что i в знаменателе означает, что фаза, восстановленная БПФ, не будет равна 60 °, хотя входная синусоидальная волна имеет фазу 60 °. Вместо этого фаза бункера FFT будет 60 - 90 градусов, начиная с -90 ° = angle(1/i) = angle(-i). Так что это на самом деле правильный ответ! Чтобы восстановить фазу синусоидальной волны, вам нужно добавить 90 ° к фазе БПФ.

Итак, подведем итог, вам нужно исправить две вещи:

  1. убедитесь, что вы смотрите на правой по частоте. Для N-точка БПФ (и не fftshift), бункеров [0 : N - 1]/N * fs. Выше мы просто использовали БПФ N = 2000 точек, чтобы обеспечить отображение 200 Гц.
  2. Поймите, что, хотя у вас есть синусоидальная волна, что касается БПФ, она получает две сложные экспоненты при +200 и -200 Гц и с амплитудами 1/(2i) и -1/(2i) , Это мнимое значение в знаменателях сдвигает фазу, которую вы ожидаете на -90 ° и + 90 ° соответственно.
    • Если вы случайно использовали cos, косинусоида, для sig, вы бы не столкнулись с этой математической преграду, поэтому обратите внимание на разницу между грехом и соз в будущем!
+1

Если бы не грех, я бы сегодня так не научился. :-). Кстати, я просто уменьшил количество образцов в моей оригинальной программе на 1 [0 до 1 - 1/fs] и получил -30. Что соответствует выводу Эйлера. Спасибо. – Raj

0

изменение t=0:1/fs:1-1/fs; затем

sig_fft_phase(201) 
ans = -30.000 
Смежные вопросы