※記事内に商品プロモーションを含むことがあります。
はじめに
NumPyのfft
パッケージを使って、FFT(Fast Fourier Transform, 高速フーリエ変換)による離散信号の周波数解析を行い、信号の振幅を求める。
環境
- NumPy 1.19
FFTの前処理
信号にFFTを掛ける前に、ローパスフィルタと窓関数を掛ける必要がある。詳細は以下のサイトを参照のこと。
11. スペクトル解析と窓関数 (やる夫で学ぶディジタル信号処理)
本記事では簡単のため、これらの前処理を省略する。
FFTを行う離散信号
次の3つの信号を合成して、フーリエ変換を行う離散信号とする。
- 周波数50[Hz], 振幅1.5の正弦波
- 周波数120[Hz], 振幅1の正弦波
- 定数項3
信号のデータ点数は1024, サンプリング周期は0.001[s]とする。
|
|
信号の波形を次のグラフに示す。
信号を0~0.1[s]の範囲に拡大した図は次の通り。
フーリエ変換の関数
前章の信号に対して関数numpy.fft.fft()
によりフーリエ変換を行う。
|
|
引数の説明は以下の通り。
a
: FFTを行う配列。
n
: FFTを行うデータ点数。None
とするとa
の長さに等しくなる。
axis
: FFTを行う配列の軸方向。指定しなければ、配列の最大次元の方向となる。
norm
: "ortho"
とすると正規化する。正規化すると変換値が1/√Nになる(Nはデータ点数)。
numpy.fft.fft()
の戻り値は、長さn
の複素数配列である。
また、関数numpy.fft.fftfreq()
によりフーリエ変換の周波数を取得する。
|
|
引数の説明は以下の通り。
n
: FFTを行うデータ点数。
d
: サンプリング周期(デフォルト値は1.0
)。
numpy.fft.fftfreq()
の戻り値は、周波数を表す配列となる。
FFTの実行とプロット
先程の信号x
に対してFFTを行い、変換結果の実部、虚部、周波数をプロットする。
|
|
周波数の配列freq
において、
- 最初の要素
freq[0]
は0[Hz] - 2~N/2 (=512) 番目の要素
freq[1:512]
は正の周波数 - (N/2+1)番目以降の要素
freq[512:]
は負の周波数
である。
元の信号の周波数が1000[Hz]であるから、サンプリング定理(または標本化定理)より、その1/2以下の周波数 (500[Hz]以下) でフーリエ変換の結果は有効である。
グラフより、周波数が0, 50, 120, -120, -50[Hz]のときに、実部や虚部がピーク値を持つことが分かる。
最後に元の信号の振幅を求める。F
をN/2
で割り、絶対値をとると振幅になる。正の周波数領域について振幅をプロットする。
|
|
結果は以下の通り。
振幅は、周波数50[Hz]で約1.42, 120[Hz]で約0.98となっており、元の値(50[Hz]で約1.5, 120[Hz]で1.0)に近い値となっている。