実データ多次元離散フーリエ変換 Multi-Dimensional DFTs of Real Data


実データの多次元離散フーリエ変換は、以下のプランナールーチンを使います。

fftw_plan fftw_plan_dft_r2c_2d( int nx, int ny,
                                double *in, fftw_complex *out, unsigned flag );
fftw_plan fftw_plan_dft_r2c_3d( int nx, int ny, int nz,
                                double *in, fftw_complex *out, unsigned flag );
fftw_plan fftw_plan_dft_r2c( int rank, const int *n,
                                double *in, fftw_complex *out, unsigned flag );

対応するc2rルーチンは、それぞれ入出力の型が入れ替わるだけです。
これらのルーチンは、複素数の出力配列が、だいたい半分になり、入出力が同じin-place変換を行う場合、実配列に余白が必要なこと以外は、複素数の場合と同様に働きます。(1dの場合と同様です)

 前述のとおり、nは配列の論理サイズで、複素配列の様式は非常に注意が必要です。実データが、行メジャー順で、n1 x n2 x n3 x・・・x ndの次元だった時を考えます。すると、r2c変換の後に出力は、行メジャー順で、n1 x n2 x n3 x・・・x(nd/2 + 1)のfftw_complexの配列で、対応する複素数離散フーリエ変換の出力の半分のサイズをわずかに上回るサイズになります。(割り算は切り捨てです)一方で、データの並びは、複素数離散フーリエ変換の場合とまったく同じになります。

 複素数データは、実データよりわずかに大きいため、入出力が同じin-place変換では、いくつか複雑な問題が生じます。この場合ですと、実データの最後の次元は、複素数データを格納するために、余白が必要となります。余白の大きさは、最後の次元が偶数か奇数かによって変わります。つまり、実データの最後の次元は、物理的に2(nd/2 + 1)個のdoubleの大きさをもちます(複素数データをちょうど格納できる大きさです)。この物理的配列サイズは、論理的配列サイズを変えることはありません。すなわち、ndの値のみが実際に最後の次元に格納され、プラン生成のルーチンに引数として渡されます。

 たとえば、nx x nyの2次元実配列の変換を考えてみましょう。r2c変換の出力は、nx x (ny/2 + 1)の2次元複素配列になり、yの次元は出力の冗長性により、およそ半分のサイズになっています。fftw_complexは、doubleの2倍の大きさであるため、出力配列は入力配列よりわずかに大きくなります。
このようにして、もし入出力が同じ変換を計算したい場合、入力配列の大きさが、nx x 2(ny/2 + 1)の大きさになるように、余白を設けなければなりません。
nyが偶数であれば、各列の最後に余白は2つになります(この余白は出力用に使われるだけなので、初期化は必要ありません)。

 以下のイラストは、今述べた入出力配列を表わしていて、in-place変換、out-of-place変換両者が示されています(矢印は、連続するメモリ領域を示しています)。

(fftw3マニュアルより抜粋)

これらの変換は、正規化されていないので、c2r変換に引き続いてr2c変換を行うと(あるいはその逆でも)、元のデータがデータ数(実データの論理次元の積)倍された結果になります

最後の次元は、特別に扱われてるため、最後の次元を1とした場合は、低い次元のr2c/c2r変換と等価にはなりません。この場合は、最後の複素数の次元は、サイズ1になり、いかなる利点も生まれません。
最終更新:2009年03月23日 01:37
添付ファイル