2016-10-01 13 views
3

私がオクターブで書いた小さなプログラムでは、望ましい位相スペクトルが得られません。マグニチュードプロットは完璧です。Octave:不正確な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)は、60度ではなく5.998(6度)を返します。私は間違って何をしていますか?私の期待は間違っていますか?あなたの例では

+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の201インデックスに相当)は199.80019980019981です。あなたは200 Hzで位相を求めていると思っていますが、そうではありません。199.8 Hzの位相を求めています。

(あなたtベクトルは1.0、つまり1個の余分のサンプルが少しスペクトル間隔が減少含まれているため、これが起こる!私は彼らのコメントで掲示リンク@Sardar_Usamaは、それが正しいこととは何の関係もありませんしませ思います正弦波が不完全サイクルこのアプローチべき作業ので、完全なサイクルで終了しないこと)

溶液:ゼロパッド1001長いsigベクトル2000のサンプルに。その後、新しいfaxis周波数ベクトル、faxis[400](Octaveの401番目のインデックス)と正確には200Hzに対応:

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°の位相を有していても、FFTによって回復される位相は60°ではないことを意味する。代わりに、-90°= angle(1/i) = angle(-i)であるため、FFTビンの位相は60 - 90度になります。これは実際に正しい答えです!正弦波の位相を回復するには、FFTビンの位相に90°を追加する必要があります。あなたは右の周波数ビンを見ていることを確認してください

  1. だから要約するために、あなたは二つのことを修正する必要があります。 NポイントFFT(およびfftshiftなし)の場合、ビンは[0 : N - 1]/N * fsです。上記では、N = 2000ポイントのFFTを使用して、200 Hzを確実に表現しています。

  2. 正弦波を持っていますが、FFTに関する限り、+ 200〜-200 Hz、振幅1 /(2i)、-1 /(2i)の2つの複素指数が得られます。 。分母のその想像上の値は、それぞれ-90°と+ 90°の位相をシフトします。
    • あなたがcosを使用していたために起こった場合は、余弦波は、sigのために、あなたは、この数学的な障害に遭遇していませんので、将来の罪とCOSとの違いに注意を払います!
+1

もしそれが罪のためでなければ、今日はとても多くのことを学んでいないでしょう。 :-)ちなみに、私は元のプログラムのサンプル数を1 [0 - 1 - 1/fs]に減らし、-30を得ました。オイラー導出に一致します。本当にありがとう。 – Raj

0

その後、t=0:1/fs:1-1/fs;に変更

sig_fft_phase(201) 
ans = -30.000 
関連する問題