
今DFTのプログラムをC言語で書いているんですが、うまく動いてくれません。
DFTの式はX(k)=1/N{Σx(k)*e^(-j2πkn/N)}のシグマの中をn=0からN-1まで足し合わせればいいと思っているのですがちがいますか。
下にプログラムを書きますのでお願いします。
void DFTcore(double x[],int N,double A[],double fai[],double a_rl[],double a_im[]){
x[]はデータ
Nはデータ数
A[]は振幅
fai[]は位相差
a_rl[]は実数部、a_im[]は虚数部
double w,a;
int k,n,t;
for(k=0;k<N;k++){ //初期化
a_rl[k]=0.0; //実数部
a_im[k]=0.0; //虚数部
}
時間間隔は1秒
for(k=0;k<N;k++){
for(n=0;n<N;n++){
w=((2*PI)/N)*k*n;
a_rl[k]=a_rl[k]+x[k]*cos(w);
a_im[k]=-a_im[k]+x[k]*sin(w);
}
a_rl[k]=a_rl[k]/(double)N;実数部
a_im[k]=-a_im[k]/(double)N; 虚数
A[k]=sqrt(a_rl[k]*a_rl[k]+a_im[k]*a_im[k]);//振幅
fai[k]=atan(a_im[k]/a_rl[k]);//位相
}
}
No.2ベストアンサー
- 回答日時:
正しくは、X(k)=1/N{Σx(n)*e^(-j2πkn/N)}
(ただし、k=f*N/f_sample , fは調べたい周波数、f_sampleはサンプリング周波数)
です。
とりあえずは、
a_rl[k]=a_rl[k]+x[n]*cos(w);
a_im[k]=a_im[k]+x[n]*sin(w);
とすれば動作確認はできます。
あとはご自分のプログラムの中でのkの意味(f*N/f_sampleは整数でなくてもよい)、f<(f_sample/2)、に注意し、プログラムを書きなおしてみてください。またきれいなスペクトルを得るには窓関数処理をお忘れなく。
数学、数式が大の苦手の私ですが、DFTはおぼろげに理解できたので、以前N88BASICという言語で(今は知っている人が少ないらしい)、DFTのプログラムを書いたことがあります。なにせクロック周波数12MHzのパソコンだったので、サインテーブルを作って積和演算の部分はマシン語で書いたり、いろいろやりました。
きれいなスペクトルが出ると感動しますよ。ご健闘を祈ります。
プログラム関する問題は解決しました、ありがとうございました。
しかし実験データから振幅の大きな周波数の周りにそれよりは小さな振幅がでているので窓関数処理をしたほうがよいみたいです。ご指摘ありがとうございました。
No.1
- 回答日時:
Σx(t)exp(-i*w*t)/N (tについての和)
をやりたいんだと思うのですが、その場合
一つのwに対してtについての和をとるわけですから
a_rl[k]=a_rl[k]+x[k]*cos(w);
a_im[k]=-a_im[k]+x[k]*sin(w);
で a_rl[]、a_im[]、x[] の [] の中が
すべて k になっているのはおかしいですよね。
さらに
a_im[k]=-a_im[k]+x[k]*sin(w);
だと1回の代入のたびに符号を反転するようになっているので
たぶんめちゃくちゃになるでしょう。
a_im[k]=a_im[k]+x[k]*sin(-w)
=a_im[k]-x[k]*sin(w)
ということがしたいのではないでしょうか?
C++をつかっているようなので
STLの<complex>を使ってみてもいいんじゃないでしょうか?
ご指摘ありがとうございます。
どうもnとkの単純な間違いだったみたいなので、お騒がせして申し訳ありませんでした。いまは正常にプログラムは走っていて、これから画像処理のほうに応用していく予定でいき、FFTにも手をだして行きたいと思っています。ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C 開放してるのにエラー(doubl...
-
プログラムでの数字につく”f”の...
-
C言語で台形公式を使った二重積...
-
c言語で、繰り返し文の中で、0....
-
至急です! マクロ定義で #defi...
-
2次方程式の解を求めるプログ...
-
C言語 関数プロトタイプ宣言の...
-
3次方程式の求解プログラム(...
-
Cプログラミングの問題です。ニ...
-
C言語を実行すると-infが出てき...
-
listに構造体を格納
-
C言語でのプログラム作成について
-
C言語の型による処理速度の違い
-
C言語のプログラムで#include<m...
-
float型とdouble型の変数の違い...
-
EXE1→DLL→EXE2数値を受け渡す方法
-
DWORDの警告
-
浮動小数点の扱い
-
^この記号を使わない
-
マチンの公式による円周率のプ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムでの数字につく”f”の...
-
C言語を実行すると-infが出てき...
-
doubleの変数にintとintの割り...
-
float型とdouble型の変数の違い...
-
c言語で、繰り返し文の中で、0....
-
至急です! マクロ定義で #defi...
-
C 開放してるのにエラー(doubl...
-
C言語の型による処理速度の違い
-
C言語 関数プロトタイプ宣言の...
-
float と double
-
ラグランジュの補間法のCプログ...
-
C言語のプログラムで#include<m...
-
c言語のコンパイルエラー canno...
-
2分法で方程式の複数の解を自...
-
2次方程式の解を求めるプログ...
-
C言語で台形公式を使った二重積...
-
Cプログラミングの問題です。ニ...
-
物体が往復する動きを作りたい
-
関数におけるif文とreturn文に...
-
doubleは常に%lfとするべきなのか
おすすめ情報