離散フーリエ変換の直流成分を中心に持ってくる方法

普通の離散フーリエ変換は直流成分は角にくるようです。知らなかった。。。これのデバッグに8時間以上費やしたhoshimiですが、ここではフーリエ変換で中心に持ってくる方法について説明(自分用)したいと思います。

ちなみに今回はfftwというフーリエ変換ライブラリを使ってます。詳しくはhttp://d.hatena.ne.jp/hoshimi_etoile/20070802を参照ください。
画像をdouble matrix;の行列としたとき、直流成分を中心に持ってくるためにはsign = 1の時に複素成分を負をかけてフーリエ変換後もう一度sign = 1についてもう一度複素成分に負をかければOKです。

といってもわかりにくいと思うのでサンプル

#include<fftw3.h>
#include<math.h>
void fft2d(double* matrix){
	//数値配列の宣言
	fftw_complex *in,*out;
	//フーリエ変換設定の宣言
	fftw_plan p;
	//数値配列用のメモリの確保
	in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nx * ny);
	out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * nx * ny);
	//入力に値を挿入
	for(int i = 0; i < width;i++){
		for(int j=0; j < height;j++){
			in[i*height + j][0] = matrix[i*height + j];
			in[i*height + j][1] = 0;

 			//直流成分を中心にするなら
			if( (i+j) % 2 == 1){
				in[i*height + j][0] *= -1;
				in[i*height + j][1] *= -1;
			}
		}
	}
	//フーリエ変換の設定
	p = fftw_plan_dft_2d(nx,ny,in,out,FFTW_FORWARD,FFTW_ESTIMATE);
	//フーリエ変換の実行
	fftw_execute(p);
	for(int i = 0; i < width;i++){
		for(int j=0; j < height;j++){
			//直流成分を中心にするなら。
			if( (i+j) % 2 == 1){
				out[i*height + j][0] *= -1;
				out[i*height + j][1] *= -1;
			}
			matrix = out[i*height + j][0] / ::sqrt(width*height);
		}
	}
	//メモリの解放
	fftw_destroy_plan(p);
	fftw_free(in);
	fftw_free(out);
}

こんな関数を作れば直流成分が中心に来るようです。
ちなみにこの証明は・・・勉強しておきます。
フーリエ変換そろそろ真面目に勉強しようかな。疎かにしてました。