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日授業開始時に集める