5

私はFFTW3を使用してC++で2D実数FFTを計算しています。マニュアルを読みましたが、いくつか質問があります。マニュアルから:http ://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data

これらの速度とスペースの利点と引き換えに、ユーザーはFFTWの複雑な変換の単純さの一部を犠牲にします。まず、入力配列と出力配列のサイズとタイプは異なります。入力はn個の実数で、出力はn / 2 + 1個の複素数(非冗長出力)です。これには、インプレース変換のために入力配列のわずかな「パディング」も必要です。次に、逆変換(複雑から実数へ)には、デフォルトで入力配列を上書きするという副作用があります。これらの不便さはどちらもユーザーに深刻な問題を引き起こすことはありませんが、それらを認識することは重要です。

  1. 入力2D行列を行順の1Dベクトルに変換する必要があることを理解しています。しかし、出力はどのように見えますか?n / 2 + 1の数値はどういう意味ですか?言い換えると、2Dマトリックスを取得するために出力を並べ替えるにはどうすればよいですか?

  2. この「パディング」を作成するには、具体的に何をする必要がありますか?

4

2 に答える 2

2
  1. 入力がすでに通常のC++2D配列にある場合は、次のように型キャストするだけです。

    double twoDarray[10][10];
    double *oneDarrayPointer = (double *)twoDarray;
    

    入力が100の場合(上記の例のように)、出力配列は51の複素数になります。これらの数値の形式はライブラリで説明する必要がありますが、おそらくdoubles102〜51エントリ×2(実数/虚数部)の配列です。

    編集:確認済み-fftw_complex次のように定義されます:

    typedef double fftw_complex[2];
    

    doublesつまり、これらは複素数の実数部と虚数部を表す連続したペアです。

  2. その場でそれを行いたくない場合は、何も埋める必要はありません。適切なサイズの出力配列を割り当てるだけです。それを適切に行う必要がある場合は、入力バッファーに、入力サイズに対して2つの追加のdouble用のスペースが必要です。上記の宣言を想定すると、次のようなものが必要になります。

    double *inPlaceFFTPointer = malloc(sizeof twoDarray + 2*sizeof(double));
    memcpy(inPlaceFFTPointer, oneDarrayPointer, sizeof twoDarray);
    

    最後の2つのエントリに必ず含める必要があるかどうかは0.0わかりませんが、追加するのは簡単です。

于 2013-01-28T23:31:26.517 に答える
2

FFTW3の実際の変換を見ることができます。これは、まさにあなたが求めていたものを実行します。これらはパディングを必要とせず、波数0とナイキスト周波数を表す波数の両方が実数成分のみを持っていることを考慮に入れています。ここを見てください:

FFTW3実数から実数への変換

およびメモリ内のレイアウトの場合:

FFTW3実数から実数への変換の種類

于 2013-10-17T07:46:41.227 に答える