1

fftwppを使用して、データと畳み込みカーネルの両方をフーリエ空間に変換し、スカラー積のようにそれらを乗算して、実空間に変換し直します。プログラムを最初に実行すると、完全にゼロで埋められた配列が作成されます。もう一度実行すると、望ましい結果が得られます。

実行中に、wisdom3.txtが作成されます。削除すると、ゼロで埋められた配列を再度作成するのに時間がかかります。

私のコードの何が問題になっていますか?

// sx, sy and sz are the dimensions of my data

int szp = sz / 2 + 1;
size_t align = sizeof(Complex);

// creates arrays to store the data in, the double one is for the real data
// the Complex one for the fourier data
array3<double> f(sx, sy, sz, align);
array3<Complex> g(sx, sy, szp, align);

// copying data into double array
for(int k = 0; k < sz; k++)
    for(int j = 0; j < sy; j++)
        for(int i = 0; i < sx; i++)
            f(i, j, k) = data[i + sx * j + sx * sy * k];

// transforming data into fourier space
rcfft3d Forward3(sz, f, g);
Forward3.fft(f, g);


// generate the kernel
array3<double> kernel(sx, sy, sz);
array3<Complex> kernel2(sx, sy, szp, align);
// more code to create the kernel left out ...


// transform the kernel into the fourier space
rcfft3d ForwardKernel3(sz, kernel, kernel2);
ForwardKernel3.fft(kernel, kernel2);


// multiplying data and kernel in fourier space together
for(int k = 0; k < szp; k++)
    for(int j = 0; j < sy; j++)
        for(int i = 0; i < sx; i++)
            g(i, j, k) = g(i, j, k) * kernel2(i, j, k);


// transform back to normal space
crfft3d Backward3(sz, g, f);
Backward3.fftNormalized(g, f);


// putting everything in the results array and normalize
for(int k = 0; k < sz; k++)
    for(int j = 0; j < sy; j++)
        for(int i = 0; i < sx; i++)
            result[i + sx * j + sx * sy * k] =
                (f(i, j, k) >= thresholdValue ? f(i, j, k) : 0);
4

1 に答える 1

3

FFTW++はFFTWのラッパーです。FFTWでは、データを効率的に処理するための実行プランを生成する必要があります。計画が生成されると、それを再利用してさまざまなデータセットを処理できます。表示されているファイルはwisdom3.txt、プログラムが最初の実行時に生成する計画に関する情報です。存在すると、連続して実行されるときにロードされ、プログラムを高速に実行できるようになります。それを削除すると、FFTWはそれを再生成する必要があり、プログラムの実行が再び遅くなります。

最初の実行で出力がゼロになる理由は、この計画生成ステップによるものです。それはFFTWFAQで説明されています。

結論として、私はFFTW ++を使用したことがないので、FTを実行する前に計画が生成されることを確認するために呼び出す必要のある正確なメソッドがわかりません。ただし、入出力配列を定義した直後、データで初期化する前に呼び出す必要があります。また、コードを複数回実行する必要がある場合は、wisdomファイルを保持する必要があります。

于 2011-03-23T20:49:04.407 に答える