ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

フーリエ変換コミュの高速フーリエ変換のアルゴリズムについて

  • mixiチェック
  • このエントリーをはてなブックマークに追加
C言語で高速フーリエ変換のルーチンを理解したかったのですが、、、よくわかりません、、、どのように、フーリエ変換の式とアルゴリズムが合致するのか。。。。orz

wikipedia等でもよくわからなくてこまっています

一様。。。フーリエ変換の定義式は理解しているつもりなんですが・・・フーリエ級数、フーリエ展開から勉強してきて、、、フーリエ複素級数展開をして。。。拡張して、、回転因子入れ込んでコンパクト定式化まで書いて感動したのですが。。。だめでした、、、アルゴリズムと合致しなくて(頭の中で・・・)orz

よろしくおねがいいたします。

/*########################################
C言語で書く高速フーリエ変換のルーチン
ニューメリィカルレシピ in C(英語版)より
#########################################*/

コメント(8)

仮面のVIPガイ
#include <stido.h> /*stidoヘッダ読み込み*/
#include <math.h> /*mathヘッダ読み込み*/

/*defineで SWAPを定義? 数字以外でdefineって使えたの? temprはグローバル変数になってるの?*/
/*SWAPでaとbの中身入れ替え*/
#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr


/*下の void four1(−−中−−)の 中で変数や配列宣言してるのと、関数の中で宣言してるのは何が違う?*/
void four1(float data[], unsigned long nn, int isign)
{
unsigned long n,mmax,m,j,istep,i;
/*整数型、unsigned long(int) 32bit幅 符号無し(倍長)整数型 0〜4294967295まで使用可能*/
double wtemp,wr,wpr,wpi,wi,theta;
/*浮動小数点型 double 64bit幅 倍精度実数型 10^-308〜10^308まで使用可能(有効桁数15)*/
float tempr,tempi;
/*浮動小数点型 double 32bit幅 単精度実数型 10^-38〜10^38まで使用可能(有効桁数7)*/

n=nn << 1;
/*nにnnを1ビット、左にシフト、して代入*/

j=1; /*j=1でjに1を代入*/

for (i=1;i<n;i+=2)
/*iが1から2づつ増えていくループ、i<nは何? i<= 繰り返し回数の書き方だから書き間違えなのかな?*/
{
/*forループ内*/
if (j > i) /*もし j が i より大きい場合 のみ */
{
SWAP(data[j],data[i]);
/*配列data[j](全部?かな? jがiより大きい場合の番目の配列どうしだけ入れ替え?)と配列data[i](全部?)の中身を入れ替える*/
SWAP(data[j+1],data[i+1]);
/*上同様、+1番目同士の入れ替え*/
/*ifの条件文終わり*/
}

m=n >> 1; /*m=n で m に n を1ビッド右にシフト(1/2)したものを代入*/

/*while文で mが2以上 かつ jがmより大きい場合、ループ終了*/
while (m >= 2 && j > m)/*論理演算、A かつ B、 A && B*/
{
/*whileのループの中*/

j -= m; /*jからm数値を減算する*/

m >>= 1;
/*a = a >> b;はa >>= b;と同じだから、mを1ビット右にシフトしたものをmに再度代入(1/2)*/

/*whileループ終了*/
}

j += m; /*jにmを加え、またjに代入(jをmふやしていく)*/

/*forのループ終了*/
}




mmax=2; /*mmaxに2を代入*/

/*nがmmaxより大きくなったらループ終了*/
while (n > mmax)
{
/*while文の中*/
istep=mmax << 1; /*istepにmmaxを左に1回ビッドシフトしたものを代入(2倍する)*/

theta=isign*(6.28318530717959/mmax);
/*シータに(=) istep に 2パイ を mmaxで割ったものの積をとり、代入*/

wtemp=sin(0.5*theta);
/*wtempにsin(0.5×シータ)*/

wpr = -2.0*wtemp*wtemp;
/*wpe に -2×(wtemp)^2 を代入*/

wpi=sin(theta);
/*wpi に sin(シータ)を代入*/

wr=1.0;
/*wr に 1 を代入(定義)、while文のなかで?何回も定義する意味あるの?*/

wi=0.0;
/*wi に 0 を代入(定義)、while文の中で?何回も定義する意味あるの?*/


/*mが1から、mがmmaxより小さくなるまで、mに2を加え増やしつづけるループ*/
for (m=1;m<mmax;m+=2)
{
/*whileループの for 文の中*/


/*i=mから、i と n の数値が同じ、もしくは i が n より小さくなるまで i に istepを加えつづけるループ*/
for (i=m;i<=n;i+=istep)
{
/*whileループの forループの for文の中*/
j=i+mmax; /*jに iにmmaxを足したものを加える*/

tempr=wr*data[j]-wi*data[j+1];
/*temprに wr×data[j] からwi×data[j+1]を 減 算したものを代入*/

tempi=wr*data[j+1]+wi*data[j];
/*temprに wr×data[j] からwi×data[j+1]を 加 算したものを代入*/

data[j]=data[i]-tempr;
/*data[j]に data[i]から temprを 減 算したものを代入*/

data[j+1]=data[i+1]-tempi;
/*data[j+1]に data[i+1]からtempiを減算したものを代入*/

data[i] += tempr;
/*data[i]に temperを 加 算したものをdata[i]に代入*/

data[i+1] += tempi;
/*data[i+1]に temperを 加 算したものをdata[i+1]に代入*/


/*whileループの forループの forループ終了*/
}

wr=(wtemp=wr)*wpr-wi*wpi+wr;
/*wr に (前のwrをwtempに代入した) wtemp×wpr から wi×wpi減算したものに wrを加算したものを代入する*/

wi=wi*wpr+wtemp*wpi+wi;
/*wiに (前の)wi × wpr にwtemp × wpi を加算、(前の)wiをさらに加算*/


/*whileループの forループ終了*/
}


mmax=istep; /*mmaxにistepを代入*/

/*whileループ終了*/
}

/*ルーチン終了*/
}
/*a>b と a >= bの違いはなに?*/

/*############################################################
##############################################################
##############################################################

確認のためのメモ

0.フーリエ変換定義式 (多少wikipediaのと違いけど、文字が違うだけ)
    N-1    jk         -2πi / N
A = Σ a W , W = e  
 k   j=0  j  N    N      

1.論理演算:A かつ B の書き方 => A && B

2.離散フーリエ変換(高速フーリエ変換の式等) wikipedia 参照(高速フーリエ変換で検索):http://ja.wikipedia.org/wiki/%E9%AB%98%E9%80%9F%E3%83%95%E3%83%BC%E3%83%AA%E3%82%A8%E5%A4%89%E6%8F%9B

3.主の頭が悪いので、式からどのようにこのアルゴリズムになったのか理解できないので、使いたいけど、よくしらないとツールとして十分に使えないので知りたい

4.ソースは 「ニューメディカルレシピ in C」から引用、(英語)

5.主はCの文法にすべて確認のためにコメントをつけましたが、あっているか疑ってかかってほしいです(まちがってるかもなので)

6.約3ヶ月苦しんでます、不甲斐無い主を誰か助けていただければ幸です。

7.主はフーリエ級数、フーリエ展開、フーリエ複素級数展開(コンパクトな回転因子、expを使用した形)、フーリエ変換の定義式までの理解する道のりを、とりあえず、フーリエの冒険を5回くらい読んで理解したつもりですが、もしかしたら知らないこともあるかもしれないので、ご了承ください。

以下:種類 : 演算子 : 結合規則 : 優先順位(下に書いているのが低い、上が高い)で明記

関数, 添字, 構造体,後置増分減分 : () [] . -> ++ -- : 左=>右
前置増分減分, 単項式 : ++ -- ! ~ + - * & sizeof : 左<=右
キャスト : (型)   : 左<=右
乗除余  : * / % : 左=>右
加減 : + - : 左=>右
シフト  : << >> : 左=>右
比較 : < <= > >= : 左=>右
等値 : == != : 左=>右
ビットAND : & : 左=>右
ビットXOR : ^ : 左=>右
ビットOR : | : 左=>右
論理AND : && : 左=>右
論理OR : || : 左=>右
条件 : ? : 左<=右
代入 : = += -= *= /= %= &= ^= |= <<= >>= : 左<=右
コンマ : , : 左=>右


###############################################################
###############################################################
#############################################################*/
私もそんなに知っているわけではありませんが・・・(MATLABでFFTと唱えているだけですので)

とりあえず,このHPのテキストに高速フーリエ変換のアルゴリズムが載っていると思いますのでご参考にどうぞ.
http://www.ykt.info.gifu-u.ac.jp/dsp.html#dsp

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

フーリエ変換 更新情報

フーリエ変換のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。