限定しりとり

離散フーリエ変換のプログラムをC言語で書きました.
周波数スペクトルを得るときに,grは-3と3(Hz)で8,giは-1と1(Hz)でそれぞれ16,-16,そのほかの周波数では0の値を取るようにしたいのですが,そのようになりません.
どうすればそんな結果を得ることができるか教えていただきたいです.
よろしくお願いします。

以下,プログラム

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main()
{
    int n, N = 32, k;
    double t, *g, *r_data, *i_data, *s_data, gr, gi;

    g = (double*)malloc(sizeof(double)*N);
    r_data = (double*)malloc(sizeof(double)*N);
    i_data = (double*)malloc(sizeof(double)*N);
    s_data = (double*)malloc(sizeof(double)*N);

    /*入力データ*/
    for(n = 0; n < N; n++){
        t = (double) (n * 3) / 32;
        g[n] = sin(2 * (M_PI) * t) + 0.5 * cos(6 * (M_PI) * t);
        printf("g[%d] = %lf\n", n, g[n]);
    }

    /*離散フーリエ変換と周波数スペクトル*/
    for ( k = -(N/2); k < (N/2); k++ ){
        gr = 0;
        gi = 0;
        for(n = 0; n < N; n++){
            gr = gr + g[n] * cos(2 * (M_PI) * k * n / N);
            gi = gi - g[n] * sin(2 * (M_PI) * k * n / N);
        }
        r_data[k] = gr;
        i_data[k] = gi;
        s_data[k] = sqrt(r_data[k] * r_data[k] + i_data[k] * i_data[k]);
    }

    /*結果の表示*/
    for(k = -(N/2); k < (N/2); k++){
        printf("gr[%d] = %lf, gi[%d] = %lf\n", k, r_data[k], k, i_data[k]);
    }

    for (k = -(N/2); k < (N/2); k++) {
        printf("gs[%d] = %lf\n", k, s_data[k]);
    }

    free(g);
    free(r_data);
    free(i_data);
    free(s_data);

    return 0;
}

質問者からの補足コメント

  • すみません,負になるのはわかるのですが...
    どこを変えるのかというのがピンと来なくて...
    もう少し教えていただけたらありがたいです...

    No.1の回答に寄せられた補足コメントです。 補足日時:2021/01/20 12:00

A 回答 (5件)

例えば


r_data[k+N/2] = gr;
とか
r_data[(k+N)%N] = gr;
にすれば (少なくとも今の場合については) いけるはず.
    • good
    • 0
この回答へのお礼

助かりました

お返事ありがとうございます!
そちらを見て考えてみてやっと理解できるようになりました...!
結果も大丈夫でした.
本当にありがとうございます!

お礼日時:2021/01/21 12:25

うん, その方が普通じゃないかな.



このプログラムだとフーリエ変換するときに使う三角関数の周期は N なので, m を整数としたとき
k=m と k=m+N では同じ結果になる
はずだよね. そして, k を 0 から回すようにすると配列の添え字とフーリエ係数とがそのまま対応するようになるので, 後の処理がわかりやすいはず. 例えば, フーリエ係数をいじってから逆変換するとかね.

あと, s_data を計算するところは, 可能なら hypot って関数を使うようにすると安全.
    • good
    • 0
この回答へのお礼

ありがとう

なるほど...
kの表示をどうしたいかで決めたのですが,他に何かやりたいことがあれば,kが負にならないほうが全体的にわかりやすくなる,という感じですね!
丁寧に説明していただいて本当にありがとうございます!
非常に助かりました!

お礼日時:2021/01/22 20:28

ちなみに.



多くの場合「k は負にしない」んじゃないかな. その方が (ちょっとだけど) 簡単だし.
    • good
    • 0
この回答へのお礼

そうなんですか!
その場合は,
for ( k = 0; k < N; k++ )
に変えるという感じでしょうか

お礼日時:2021/01/22 13:35

方針としては


・k が負にならないようにする
・k が負であってもよいようにする
のどっちもとれるけど, どっちがいい?
    • good
    • 0
この回答へのお礼

お返事ありがとうございます。
では、kが負であってもいいようにお願いしたいです

お礼日時:2021/01/20 20:35

たとえば


r_data[k] = gr;
のところ, まさかとは思いますが k が負になることを忘れてはいないですよね?
この回答への補足あり
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!