Processing math: 100%

[NumPy]FFTでフィルタリング ①フーリエ級数展開と離散フーリエ変換

時系列解析というか信号解析で、任意特性のデジタルフィルタを適用したいことがありました。
基礎的な数学の知識も無ければ、Python・NumPyにも不慣れな私が、試行錯誤というか実際に手を動かしてみた結果を、自らの備忘録をかねてとりまとめてみたところです。

フーリエ級数展開

フーリエ変換に入る前に、フーリエ級数展開について触れておきたいと思います。
数学的な正確性を度外視してしまえば、全ての関数f(t)は三角関数で近似できるというものです1)フーリエ級数|展開の仕組みと計算方法2)フーリエ級数展開の公式と意味|高校数学の美しい物語

f(t) = \frac{a_{0}}{2}+\sum_{k=1}^{\infty}[a_{k}・cos(kt)+b_{k}・sin(kt)]

この式なら、大学レベルの知識の無い私でも理解できました。
さて、この式は複素数の指数関数で表すことが出来ます。

f(t) = \frac{a_{0}}{2}+\sum_{k=-\infty}^{\infty}[c_{k}・exp(-i・t)]

三角関数の式では0 \leq k \leq \inftyだったのに対して、複素指数関数表記では-\infty \leq k \leq \inftyとなっています。
ちなみに、複素数の指数関数と三角関数はオイラーの公式で繋がっています

exp(z・i)=cos(z)+i・sin(z)

NumPyのFFT

さて、ここから本題です。
周波数Fのデータ(信号)を考えたいと思います。

f(t) = sin(2πFt)

周波数1Hz、振幅1の波形

このデータを、データ長:N、サンプリング周波数:f_{s}として離散化して、下記のPythonコードで離散フーリエ変換をしてみたいと思います。
できるだけ本文中の記号と、コード中の変数名を合わせようとしていますが、限界がある点はご容赦ください。

1
2
3
4
5
6
7
8
9
10
11
12
13
import os
import numpy as np
 
# サンプルデータ設定
= 200 #データ長
FS = 100 #サンプリング周波数[Hz]
FF = 1   #信号の周波数
 
ts = np.arange(0, N * 1/FS, 1/FS) #時刻列
signal = np.sin(FF*ts*2*np.pi)    #信号列
 
signal_f = np.fft.fft(signal)       #離散フーリエ変換
freqs = np.fft.fftfreq(N, d=1.0/FS) #周波数列

np.fft.fftに信号(時系列データ)を流し込むことで離散フーリエ変換が行われ、時間領域から周波数領域に
離散フーリエ変換の結果はsignal_fに、signal_fに対応する周波数は変数freqsに格納されています。

上記のコードを実行すると、変数「freqs」に周波数が格納されています。この変数「freqs」
実際に格納されている値を見てみましょう。

k freqs[k] f_k
0 0.0 \frac{kf_s}{N}
1 0.5 \frac{kf_s}{N}
2 1.0 \frac{kf_s}{N}
・・・
99 49.5 \frac{kf_s}{N}
100 -50.0 \frac{kf_s}{N}-{f_s}
101 -49.5 \frac{kf_s}{N}-{f_s}
・・・
198 -1.0 \frac{kf_s}{N}-{f_s}
199 -0.5 \frac{kf_s}{N}-{f_s}

格納されている値を見ると、0から0.5Hzずつ上がっていった後に、k=100のところで突然-50.0Hzになり、そこから0.5Hzずつ上がっています。
なぜ、k=100のところで、突然-50Hzになるかというと、標本化定理によりサンプリング周波数の半分の周波数(ナイキスト周波数)までしか表現できないということに関係しています。つまり、周波数f_kの取り得る値は、
-\frac{f_s}{2} \leq f_k \leq \frac{f_s}{2}
となります。

さて、FFTの結果「signal_f」の値について踏み込みたいところですが、話が長くなってきたのでいったん筆を置きたいと思います。

続きは↓
[NumPy]FFTでフィルタリング ②離散フーリエ変換

補足

FFTの周波数列について、少し一般化してみました。
ここで、M=int(\frac{N}{2})とし、「int」は小数点以下を切り捨てる関数とします。

k f_k
0 0
1 \frac{f_s}{N}
2 \frac{2f_s}{N}
・・・
M-1 \frac{(M-1)・f_s}{N}
M \frac{M・f_s}{N}-f_s
M+1 \frac{(M+1)・f_s}{N}-f_s
・・・
N-2 \frac{(N-2)・f_s}{N}-f_s
N-1 \frac{(N-1)・f_s}{N}-f_s