東北工業大学 工学部情報通信工学科 中川研究室


離散フーリエ変換(DFT)

前のページから
c言語の書き方例


am = (2/N) Σk=0N-1 { fk cos(2pmk/N) }
bm = (2/N) Σk=0N-1 { fk sin(2pmk/N) }

いろんなm
m = 1, 2, 3, ... N/2 の場合についても a1, a2, a3, ... をすべて求めたいので、
mについてもループにすればいいですね。
aも bも、角度の計算は同じなので、1回計算して ang に代入でいいよね。

これ以降、ベタにわかりやすいよう、個数N をKOSU と書いていきます。

for ( m=0; m<=KOSU/2; m++ ){
a = 0.0;
b = 0.0;
for ( k=0; k<KOSU; k++ ){
ang = 2 * PI * m * k /KOSU;     ←角度 (aとbに2回使うので)
a = a + f[k] * cos( ang );
b = b + f[k] * sin( ang );
}
a = a * 2 /KOSU;
b = b * 2 /KOSU;
if( m == 0 || m == KOSU/2){ ←m = 0 または m=KOSU/2の時は特別
a = a/2;
b = b/2;
}
p = a* a + b* b; ←振幅を2乗するとパワーが求められます
printf("m= %d a= %f b= %f power= %f \n", m, a, b, p ); ←得られた結果を出力
}


データ入力
(手動)
これ以前に、あらかじめ f[0], f[2], f[3], ... f[KOSU-1] にデータを入力しておく必要がありますね。
キーボードからデータ入力するなら、scanfでできそうですね


準備いろいろ scanf を使うなら stdio.h を include,
sin や cos を使うなら math.h を include する必要があります。
プリプロセッサとして書きます。
pre(前)のprocessor(処理)という意味なので、main()より前に書きます。
プリプロセッサの書き方例


使う変数m, k, a, b, ang, p の型宣言も必要です。
main() の中の一番最初に書きます。
int m, k; float f[KOSU], a, b, ang, p; /* --- f[0] to f[ KOSU-1 ] --- */ 配列f[] のデータの個数KOSUは、変数ではなく、プリプロセッサによって数値に書き換えられます。

手動入力例 これらをまとめて、キーボードからデータを手入力してDFTするプログラムにした例です。

動きます。
だけど正直、データが多い時とか、やり直すたびに手入力ではやってられないです。
データファイルを開いて、そこから読めるようにならないと実際困ります。


データ入力
(ファイルから)
ファイルからデータ入力するなら、
ファイル名を指定して、
そのファイルを openして、
fscanfで読み込みですね


中川研HOME