2016-08-07 1 views
2

numpyの高速フーリエ変換の実装では苦労しています。私の信号は周期性のものではなく、理想的な候補ではありませんが、FFTの結果は私が期待していたものとはまったく異なります。それは単に同じシグナルであり、単純に何らかの要因で引き伸ばされています。私は正しくFFT機能を使用することを、説明すべきその横に私の信号を近似する、洞曲線をプロット:numpyの高速フーリエ変換により予期しない結果が生じる

import numpy as np 
from matplotlib import pyplot as plt 

signal = array([[ 0.], [ 0.1667557 ], [ 0.31103874], [ 0.44339886], [ 0.50747922], 
    [ 0.47848347], [ 0.64544846], [ 0.67861755], [ 0.69268326], [ 0.71581176], 
    [ 0.726552 ], [ 0.75032795], [ 0.77133769], [ 0.77379966], [ 0.80519187], 
    [ 0.78756476], [ 0.84179849], [ 0.85406538], [ 0.82852684], [ 0.87172407], 
    [ 0.9055542 ], [ 0.90563205], [ 0.92073452], [ 0.91178145], [ 0.8795554 ], 
    [ 0.89155587], [ 0.87965686], [ 0.91819571], [ 0.95774404], [ 0.95432073], 
    [ 0.96326252], [ 0.99480947], [ 0.94754962], [ 0.9818627 ], [ 0.9804966 ], 
    [ 1.], [ 0.99919711], [ 0.97202208], [ 0.99065786], [ 0.90567128], 
    [ 0.94300558], [ 0.89839004], [ 0.87312245], [ 0.86288378], [ 0.87301008], 
    [ 0.78184963], [ 0.73774451], [ 0.7450479 ], [ 0.67291666], [ 0.63518575], 
    [ 0.57036157], [ 0.5709147 ], [ 0.63079811], [ 0.61821523], [ 0.49526048], 
    [ 0.4434457 ], [ 0.29746173], [ 0.13024641], [ 0.17631683], [ 0.08590552]]) 

sinus = np.sin(np.linspace(0, np.pi, 60)) 

plt.plot(signal) 
plt.plot(sinus) 

青い線が緑の線が洞で、私の信号です。

raw.pdf

transformed_signal = abs(np.fft.fft(signal)[:30]/len(signal)) 
transformed_sinus = abs(np.fft.fft(sinus)[:30]/len(sinus)) 

plt.plot(transformed_signal) 
plt.plot(transformed_sinus) 

青い線は緑色の線は、transformed_sinusで、transformed_signalです。のみtransformed_signalをプロット

fft.pdf

は、上記の動作を示しています

enter image description here

誰かがここで何が起こっているのか私に説明できますか?

UPDATE

私は確かにFFTを呼び出すの問題でした。私はステリオスで述べた重要な事を見落とし

transformed_signal = abs(np.fft.fft(signal,axis=0)[:30]/len(signal)) 

enter image description here

答えて

3

Numpyのfftは、デフォルトで行に適用されます。 signal変数は列ベクトルなので、1つの要素からなる行にはfftが適用され、各要素の1点FFTが返されます。

すなわち、

transformed_signal = abs(np.fft.fft(signal,axis=0)[:30]/len(signal)) 
+0

あるいは、signalが1Dベクトルであることが意図されているなら、 'np.array([signal in x]のx [0])' – mtrw

1

[EDIT]:これは正しいコールと正しい結果です!それにもかかわらず、私はあなたのトラブルの根本的な原因を突き止めることはできませんが、これはまだ真実であり、使用可能なFFTのために考慮しなければならないことを含んでいます。

あなたは、非定期信号をトランスフォームすると言います。 信号にFFTにうまく表示されるいくつかのリップル(高調波)があります。 正弦波の周波数ははるかに低く、主にDC成分で構成されています。

これまでのところとても良いです。私の理解していないことは、あなたの信号にもDC成分があることです.DC成分は全く現れません。これは規模の問題である可能性があります。

コアの問題は、洞結節と信号が全く同じに見えますが、それらはまったく異なる高調波成分を持っていることです。

両者のうち最も顕著なものは、半洞に対応する周波数を保持していません。これは、全体の洞穴を合計することによって '半洞'が構築されないためです。言い換えれば、基礎を成す全洞波は、洞の半分以上のスペクトル内容にない。

サンプル数がわずかであるため、サンプル周波数は信号周波数の2倍以上にする必要があります。それ以外の場合はエイリアシングが発生します(間違った場所に周波数をマッピングする)。言い換えれば:あなたの信号はサンプリング後に視覚的に滑らかに見えるはずです(もちろん、不連続であるか、またはブロックまたは三角波のような不連続な微分がない限り)。しかし、あなたのケースでは、鋭いピークがアンダーサンプリングの人工物であるように見えます。

+0

、あなたはFFTがsignalの列の上に適用することを指定しfftの軸オプションを使用して、私はFFTに非常に新しいですし、完全にあなたの答えを理解していません。私は、信号がFFTとは全く違って見え、そのために全く異なる結果が生じることを理解していると思います。しかし、私はあなたがDCコンポーネントで何を意味するか分かりません。なぜあなたはそこにいるべきだと思いますか?そして、この可能性のあるスケール問題を緩和するためにあなたは何をするべきですか?私はエイリアシングを説明するために、より長い信号を見つけようとします。 – Paul

+0

@Paul Jacquesは、[Nyquist-Shannon sampling theorem](https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem)を参照しています。サンプリング周波数は、キャプチャしたい信号の最高周波数成分の周波数の2倍にする必要があります。 –

+0

表示として、検出したい最低周波数から最低20フル・ピリオド、最高周波数からフル・ピリオドを少なくとも2サンプル使用してください。また、シグナルの不連続性とその導関数を防ぐために、開始時と終了時にシグナルを徐々に減衰させます(したがって、デリバティブがジャンプするので、ゼロでカットオフすることはできません)。 –

関連する問題