今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]);//位相

}
}

このQ&Aに関連する最新のQ&A

IM 意味」に関するQ&A: WINMXのIMの意味が・・

A 回答 (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のパソコンだったので、サインテーブルを作って積和演算の部分はマシン語で書いたり、いろいろやりました。
きれいなスペクトルが出ると感動しますよ。ご健闘を祈ります。
 
    • good
    • 0
この回答へのお礼

プログラム関する問題は解決しました、ありがとうございました。
しかし実験データから振幅の大きな周波数の周りにそれよりは小さな振幅がでているので窓関数処理をしたほうがよいみたいです。ご指摘ありがとうございました。

お礼日時:2001/07/09 01:53

Σ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>を使ってみてもいいんじゃないでしょうか?
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございます。
どうもnとkの単純な間違いだったみたいなので、お騒がせして申し訳ありませんでした。いまは正常にプログラムは走っていて、これから画像処理のほうに応用していく予定でいき、FFTにも手をだして行きたいと思っています。ありがとうございました。

お礼日時:2001/07/09 01:18

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q&str[n]とpstr + nと&pstr[n]

あるプログラミングの本で

&str[n]
pstr + n
&pstr[n]

は同じだと書いてあり、考えたのですが、
上の二つはstr[n]のアドレスを表しているとしても、
三つ目はstr[n]のポインタのアドレスを表していると思うのですが
どこが間違っているのでしょうか?教えてください。

Aベストアンサー

>本にも突然でてきているのでよくわからないのですが・・・。

よくわからないもの同士が同じかと聞かれても、よくわからないというのが答えです。
本当に、突然出てきているのなら、そんな本は捨てましょう。

Qstruct tanka_kosuu kosuu[10];の[10]て何

#include <stdio.h>
struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
};
int main()
{
         struct tanka_kosuu kosuu[10];
       構造体宣言 構造体名  変数名
struct tanka_kosuu kari_nyuuryoku = {-1, 0, 0};
int nyuuryoku_kosuu = 0;
while(kari_nyuuryoku.tanka != 0){
scanf("%d %d", &kari_nyuuryoku.tanka,
&kari_nyuuryoku.kosuu);
kosuu[nyuuryoku_kosuu] = kari_nyuuryoku;
nyuuryoku_kosuu++;
}
return 0;
}
以上ですが、
 struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
以上と
struct tanka_kosuu kosuu[10];は
 以下
int tanka;
int kosuu[10];
int kingaku;
 と同じ意味ですか?
 それとも
  int tanka[10];
int kosuu[10];
int kingaku[10]; 
 と同じ意味ですか?
int tanka[10];と
 int kingaku[10];の
 合計に[10]は必要ないですよね
以上すべて私の考え方が間違っていたならごめんなさい。
 以上よろしくお願いいたします。

#include <stdio.h>
struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
};
int main()
{
         struct tanka_kosuu kosuu[10];
       構造体宣言 構造体名  変数名
struct tanka_kosuu kari_nyuuryoku = {-1, 0, 0};
int nyuuryoku_kosuu = 0;
while(kari_nyuuryoku.tanka != 0){
scanf("%d %d", &kari_nyuuryoku.tanka,
&kari_nyuuryoku.kosuu);
kosuu[nyuuryoku_kosuu] = kari_nyuuryoku;
nyuuryoku_kosuu++;
}
return 0;
}
以上です...続きを読む

Aベストアンサー

#1です。

>struct tanka_ data { ・・・・(1)
>  int tanka;
>  int kosuu;
>  int kingaku;
>};
・・・途中省略
>} これでいいでしょうか

(1)のところは、変えてはいけません。
struct tanka_kosuu { 
のままにして下さい。
他は、問題ありません。

Qa[i]とa[i+1]を入れ替えるような関数を作成するC言語の問題

以下のように配列aとそのサイズsとインデックスiを引数
にとり、a[i]とa[i+1]を入れ替えるような関数を作成する問題。

但し、この関数内で配列の外側をアクセスしないようにエラー
チェックをすること。正常に処理が終了した場合は0を返し、
そうでない場合は-1を返すようにする。

main関数では、10個分の整数を入れる配列を宣言し、
データをユーザに入力させる。
次に、ユーザに1個整数を入力させ、0からその番号まで順に
iをずらしてswap_array関数を読んだ後、配列に入っているデータを
表示させる。

・配列にデータを入力でき、交換が正しくできている
・ユーザが配列の外側を指定した場合は、エラーである旨を
表示して終了する。

取りあえずこうゆうかんじになるのですが、//の前などをどうにすればいいか分かりません。分かる方は知恵を貸してください。

int swap_array(int a[], int s, int i)
{
//a[i]番目とa[i+1]番目を入れ替え処理をする

//正しく交換できた場合はreturn(0);
//エラーが発生した場合はreturn(-1);
}
int main()
{
//サイズ10の配列の宣言
int a[10];
//ユーザに10個のデータの入力をさせる
int i;
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
//0番目から何番目まで入れ替えるかユーザに聞く: (ユーザがnと入力)
int n;
......

//繰り返し構造を使って、0番目からn番目まで隣同士を交換
for(i=0;i<=n;i++){
int v;
// swap_arrayを繰り返し呼び出すが、毎回戻り値が0であることを
        //チェックしてエラーが発生していないことを確かめる
v=swap_array(a,10,i);

// エラーが発生していたら エラーが発生したことを表示して
//break;文で繰り返し構造から外にでる。
if(v==-1) break;
}

//エラーが発生しなかった場合に、入れ替えられた配列の内容を表示
if(v!=-1){
..... 配列の内容を表示
}

return(0);

以下のように配列aとそのサイズsとインデックスiを引数
にとり、a[i]とa[i+1]を入れ替えるような関数を作成する問題。

但し、この関数内で配列の外側をアクセスしないようにエラー
チェックをすること。正常に処理が終了した場合は0を返し、
そうでない場合は-1を返すようにする。

main関数では、10個分の整数を入れる配列を宣言し、
データをユーザに入力させる。
次に、ユーザに1個整数を入力させ、0からその番号まで順に
iをずらしてswap_array関数を読んだ後、配列に入っているデータを
...続きを読む

Aベストアンサー

こんな感じではだめでしょうか…。

#include <stdio.h>

unsigned int swap_array(int a[],unsigned int size,unsigned int s)
{
unsigned int temp,i=s;
if (size<s) return s;// 要素数を返す
while (i-1) temp=a[s-i+1],a[s-i+1]=a[s-i],a[s-i--]=temp;
return 0;
}
int main()
{
int a[10];
unsigned int n,i=0,size=sizeof(a)/sizeof(unsigned int);

do{
printf("%d個目のデータ?",i+1);
scanf("%d",&a[i]);
}while(++i<size);

//do{
printf("入れ替え対照、何番目のデータ(1~%d個)?",size);
scanf("%d",&n);
//}while(n>size || !n);
//この段階で範囲制限させる時は上記2行のコメントを解除

if (i=swap_array(a,size,n)) printf("エラー>要素数%dは範囲外です\r\n",i);
else for (i=0;i<size;i++) printf("%d個目:%d\r\n",i+1,a[i]);
return 0;
}

こんな感じではだめでしょうか…。

#include <stdio.h>

unsigned int swap_array(int a[],unsigned int size,unsigned int s)
{
unsigned int temp,i=s;
if (size<s) return s;// 要素数を返す
while (i-1) temp=a[s-i+1],a[s-i+1]=a[s-i],a[s-i--]=temp;
return 0;
}
int main()
{
int a[10];
unsigned int n,i=0,size=sizeof(a)/sizeof(unsigned int);

do{
printf("%d個目のデータ?",i+1);
scanf("%d",&a[i]);
}while(++i<size);

//do{
printf("入れ替え対照、何番目のデータ(1~%d個...続きを読む

Qint kosuu; とstruct tanka_kosuu kosuu[10]; の関係は

同プログラムの内容で現在3個の質問をしておりますが!
 その質問を解決する上で4つ目の質問をさせていただきます。
 悪しからず・・・
 さて
以下のサイトのプログラムで 些細な疑問がございます。
https://oshiete.goo.ne.jp/qa/9062058.html
 で
 struct tanka_kosuu {
int tanka; 
int kosuu; 
int kingaku; /
以上の中にあるkosuuと
 struct tanka_kosuu kosuu[10];のkosuu[10]とは直接関係がありますか?
 馬鹿な質問ばかりで申し訳ございませんがよろしくお願いいたします。

Aベストアンサー

#No.1です。

>kosuu[10];をakb[10];変えたところ 以下の errorでてコンパイルできません!?
> example10.c(15) : error C2065: 'kosuu' : 定義されていない識別子です。


宣言している変数名を変更したら、その変数を利用している場所(エラーメッセージで15行目と書かれています)の変数名も変更する必要があると思いませんか?

下の例で、1行目も変数をaからbに変えたら、2行目,3行目のaも、bに変える必要があのはご理解いただけますよね?
01: int a;
02: a = 10;
03: printf("a=%d\n", a);

Qfp = fopen(argy[1], "r");の[1]の意味は

https://oshiete.goo.ne.jp/qa/8940272.html
 の11行目に
fp = fopen(argv[1], "r");の[1]の意味が分かりません。
試したいのですが、ソフトがうまく動きません
 よろしくお願いいたします。

Aベストアンサー

前の例題も読みました。

大分苦戦しているようですが、配列については理解が進みましたでしょうか?
お答えしますと、最初のパラメータ文字列が代入されています。

古いC言語の約束でして大変有名なものです。

コマンドラインコンソールから実行ファイル名を書いて、
パラメータをスペースで区切って指定したとします。

このパラメータ文字列が[1]以降に入ります。
例として、"test"と言う名前の実行ファイルがあったとします。

例)> test test1 test2 3 4

このようにコマンドラインから入力し実行すると、

argc = 5
argv[0] = "test"
argv[1] = "test1"
argv[2] = "test2"
argv[3] = "3"
argv[4] = "4"

と文字列が入ってきます。

以下はサンプル。

void main( int argc , char *argv[])
{
if( argc < 2 )
{
// パラメータ指定がなかった場合の表示
printf( "test に続けて4つまでパラメータを入力できます\n");
exit(0);
}
if( argc > 5 )
{
 // パラメータが5つ以上あった場合の表示
printf( "5つ以上のパラメータは受け付けません\n");
exit(-1);
}

// 正常ルート
printf( "パラメータの数は%d個ですね?ニヤッ\n", argc-1);
printf( "最初のパラメータは%sでしょ?\n", argv[1]);
printf( "残りはargv[2]以降ですが、面倒なので表示しません\n");
}

と言う具合に、引数を活用できます。argv[0]には、実行ファイル名が入ります。
argc は実行ファイルの名前も含めてカウントされます。

プログラムによっては必要な引数の数が変わりますし、
ユーザーのコマンドラインからの入力ミスなどでパラメータがなかったり、
必要なパラメータが不足していたりしますので、
argcとargvを使って最初にシンタックスエラーチェックをするのが常道です。

実行ファイル名の指定がなく、プログラムが実行されることはないと思われます
から、argcは1以上の値になります。

argc, argvの活用は、
実行コマンドを手打ちで打ち込むコンソール形式でよく用いられる基本的な
アプリケーションの開発手法です。

ご質問の箇所は、
第一パラメータにプログラム内で読み込むファイルのファイル名を指定してるの
でしょう。(よくあります)

しかし、Windowsなどのウィンドウを使用するアプリケーションは、
これとは違っておりますので注意が必要です。
(C言語とは別に、Windowsに特化した開発ノウハウの勉強が必要です)

Windows系で上記の様な基本的なプログラムを作成する場合は、
プロジェクトの作成時に(VisualStudioなどで)コンソールアプリケーション
を選んで作成します。実行時にコンソールが開きます。

Linuxの場合は、コンソールがデフォルトになっているでしょうから、
(特殊な設定がなければ)そのまま作成できます。

テキストエディタでソースを記述し、gcc などでコンパイルします。
実行形式ファイルが出来ていれば、想定どおりの動作をするでしょう。

ファイルの読み込みが出来るようになったら、
ファイルの内容を書き換えて保存したり、
ファイル名を変えたり、
ディレクトリ内のファイルを全て表示したり、
ファイル内に含まれる文字列を検索し、該当するファイルをリストしたりなど、

有用なサンプルプログラムを沢山作って練習します。

ファイルを読み込む先は、char型の配列でバイトサイズのメモリーとして確保
します。メモリーと変数の関係を充分に理解することをお勧めします。
殆どのプログラムは、このメモリーの確保やメモリーサイズの計算と格闘する
場合が多くなるからです。

バイナリー形式のファイル(すべてはバイナリー形式として良いのですが)に
ついて理解が深まった後は、
bmpの画像ファイル、wavなどの音声ファイルをあけて、
これの中身を書き換えて遊びます。

特にwavファイルは、音量の変更や周波数フィルタなども掛けれますので、
メモリ、配列、ファイルの関係を(焦らずに)ゆっくり理解するだけで、
今の知識レベルでも面白いことが沢山出来ます。

以上、ご参考に成れば。

前の例題も読みました。

大分苦戦しているようですが、配列については理解が進みましたでしょうか?
お答えしますと、最初のパラメータ文字列が代入されています。

古いC言語の約束でして大変有名なものです。

コマンドラインコンソールから実行ファイル名を書いて、
パラメータをスペースで区切って指定したとします。

このパラメータ文字列が[1]以降に入ります。
例として、"test"と言う名前の実行ファイルがあったとします。

例)> test test1 test2 3 4

このようにコマンドラインから...続きを読む


人気Q&Aランキング

おすすめ情報