DFT
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #define _USE_MATH_DEFINES #include <math.h> #define N 4096 int calCount; void data_in(int, float*); void dft_sub(int, float *, float *, float *); void Ck(int n, float *Ck_r, float *Ck_i); void main(void) { int i, n; float f[N], a[N], b[N]; float Cr[2 * N - 1], Ci[2 * N - 1]; float *Ck_r, *Ck_i; //データ個数 n = 8; data_in(n, f); //フーリエ係数の初期化 for (i = 0; i < n; i++) { a[i] = 0; b[i] = 0; } //複素フーリエ係数Ckについて,マイナスのインデックスでアクセスできるようにする //例えば,n=8の時には,以下のように対応している. //C 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 //Ck -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 Ck_r = &Cr[n-1]; Ck_i = &Ci[n-1]; for (i = -(n - 1); i < n - 1; i++) { Ck_r[i] = 0; Ck_i[i] = 0; } //dft_subは,fとnを入力として, //DFTの値を計算して,その結果をa,bに入れてくれる. dft_sub(n, f, a, b); //解析値の複素フーリエ係数の実数部と虚数部を計算してCk_r,Ck_iに入れてくれる. Ck(n, Ck_r, Ck_i); printf("データ個数 n=%d \n", n); printf("k f A_k B_k Ck_Re Ck_Im\n"); for (i = -(n - 1); i < n; i++) { if (i >= 0) { printf("%3d %8.8f %8.8f %8.8f %8.8f %8.8f\n", i, f[i], a[i], b[i], Ck_r[i], Ck_i[i]); } else { printf("%3d \t \t \t \t \t %8.8f %8.8f\n", i, Ck_r[i], Ck_i[i]); } } printf("計算回数は%d\n", calCount); } /** * @fn void data_in(int n, float f[]) * @brief 指定された個数のサンプル値を返す * @param[in] n サンプルの個数 f[]の個数 * @param[in] f[] n個のサンプル値を入れる配列 */ void data_in(int n, float f[]) { int i; //方形波の時のパターンの例 /* for (i = 0; i < n; i++) { if (i < n / 4)f[i] = 1.0; if (i == n / 4)f[i] = 0.5; if (i == 3 * n / 4)f[i] = 0.5; if (i > 3 * n / 4)f[i] = 1.0; if (i > n / 4 && i < 3 * n / 4)f[i] = 0.0; } */ //4_2の波形のサンプル値をここに定義する for (i = 0; i < n; i++) { } } /** * @fn void Ck(int n, float *Ck_r, float *Ck_i) * @brief 波形から複素フーリエ係数の実数部と虚数部の値を保存する * @param[in] n サンプル個数 * @param[in] *Ck_r 計算した複素フーリエ係数の実数部の値を保存する系列のポインタ * @param[in] *Ck_i 計算した複素フーリエ係数の虚数部の値を保存する系列のポインタ */ void Ck(int n, float *Ck_r, float *Ck_i) { int i; //解析解の実数部の値と虚数部の値それぞれを //-(n-1)から(n-1)の範囲で計算する. //Ck_r[i],Ck_i[i]とアクセスする. //ただし,Ck_0は別途設定する for (i = -(n - 1); i < n; i++) { } } /** * @fn void dft_sub(int n, float *f, float *a, float *b) * @brief 波形から,DFTの実数部と虚数部の値を保存する * @param[in] n サンプル個数 * @param[in] *f 入力波形のサンプル値 * @param[in] *a 計算したDFTの実数部の値を保存する系列のポインタ * @param[in] *b 計算したDFTの虚数部の値を保存する系列のポインタ */ void dft_sub(int n, float *f, float *a, float *b) { int i, k; //a_k(a[k]とアクセスする)とb_k(b[k]とアクセスする)の値をDFTの式に従って計算する for (k = 0; k < n; k++) { } }
ソースコードファイル
課題
演習問題4.2に示されている波形について,DFTによるスペクトル(N=8)をもとめ,図示せよ.また,解析解と比較せよ.解析解についてはk=-7〜7の範囲,DFTではk=0〜7の範囲で示す.
DFTおよび,解析解のスペクトルを求める時には,提示したプログラムを用い,必要な追加部分を記入して,実行して求めること.
提出レポートには,ソースコード,図示する各係数の値の一覧を含めること.
提出方法
締切日時:5月29日授業開始時に集める