Loading [MathJax]/jax/output/CommonHTML/jax.js

5. DFT のプログラミング

プログラミングで DFT / IDFT を計算する際は通常はFFT (Fast Fourier Transform : 高速フーリエ変換) と IFFT (逆高速フーリエ変換) を利用します。
ただし、どうしても FFT /IFFT を使いたくない場合は

DFT[k]=A[k]+jB[k]

の様に DFT 係数を実数成分 A[k] と虚数成分 B[k] に分けてプログラミングすると楽です。
オイラー公式を使うと A[k]B[k] は次の様になります。

A[k]B[k] の求め方 A[k]=1NN1i=0{f[i]cos(k2πNi)}B[k]=1NN1i=0{f[i]sin(k2πNi)}

ここで

f[i] ・・・ 周期 N [点] の周期性時間領域ディジタル信号

A[k] ・・・k 番目のDFT係数の実数成分、実数の定数

B[k] ・・・k 番目のDFT係数の虚数成分、実数の定数

このようにすると DFT の演算中に複素数が含まれなくなるので、普通に外側が k、内側が i の 2 重 for ループを作って A[k]B[k] を求められます。

また次の様にして DFT 係数の絶対値と偏角も簡単に求められます。

絶対値と偏角の求め方 |DFT[k]|=sqrt(A[k]A[k]+B[k]B[k]) DFT[k]=atan2(B[k],A[k])

※ プログラミング言語によっては atan2(A[k],B[k]) の順の場合もあります

同様に IDFT を A[k]B[k] を使って書き直すと次のようになります。

A[k]B[k] を用いた IDFT f[i]=N1k=0{A[k]cos(k2πNi)B[k]sin(k2πNi)}

ここで

f[i] ・・・ 周期 N [点] の周期性時間領域ディジタル信号

A[k] ・・・k 番目のDFT係数の実数成分、実数の定数

B[k] ・・・k 番目のDFT係数の虚数成分、実数の定数

この場合は外側が i、内側が k の 2 重 for ループを作って A[k]B[k] から f[i] を復元できます。


(参考) 周期性時間領域ディジタル信号が複素信号の場合


f[i]が複素信号、つまり

f[i]=a[i]+jb[i]

の場合のDFTは次のようになります

複素信号の DFT A[k]=1NN1i=0{a[i]cos(k2πNi)+b[i]sin(k2πNi)}B[k]=1NN1i=0{a[i]sin(k2πNi)+b[i]cos(k2πNi)}

ここで

a[i] ・・・ 周期 N [点] の周期性時間領域複素ディジタル信号 f[i] の実数成分

b[i] ・・・ 周期 N [点] の周期性時間領域複素ディジタル信号 f[i] の虚数成分

A[k] ・・・k 番目のDFT係数の実数成分、実数の定数

B[k] ・・・k 番目のDFT係数の虚数成分、実数の定数

IDFTは次の通りです。

複素信号の IDFT a[i]=N1k=0{A[k]cos(k2πNi)B[k]sin(k2πNi)}b[i]=N1k=0{A[k]sin(k2πNi)+B[k]cos(k2πNi)}

ここで

a[i] ・・・ 周期 N [点] の周期性時間領域複素ディジタル信号 f[i] の実数成分

b[i] ・・・ 周期 N [点] の周期性時間領域複素ディジタル信号 f[i] の虚数成分

A[k] ・・・k 番目のDFT係数の実数成分、実数の定数

B[k] ・・・k 番目のDFT係数の虚数成分、実数の定数