私はインプレースとアウトオブプレースのFFTをFFTW3でcで理解しようとしています。まず、一次元変換を使うことにしました。私はアウトオブプレイスを最初から複雑な変換に変換してから、その変換からの複雑な出力を使用してインプレース複合を実際の変換に行い、元の実際の入力データを元に戻したいと考えました。私は、しかし、私はちょうどなぜ思っていた?これを行うための私のサンプルコードは以下の通りです。FFTW3でのインプレースFFT
#include <stdlib.h>
#include <stdio.h>
#include <complex.h>
#include <fftw3.h>
#include <math.h>
void one_dimensional_transform(void)
{
float *in;
fftwf_complex *out, *inplace;
int N = 8;
fftwf_plan plan;
int i;
FILE *fd;
// Do out of place transform. For this, in has N elements and out has N/2 + 1.
in = fftwf_alloc_real(N);
out = fftwf_alloc_complex(N/2 + 1);
inplace = fftwf_alloc_complex(2 * ((N/2) + 1));
plan = fftwf_plan_dft_r2c_1d(N, in, out, FFTW_ESTIMATE);
fd = fopen("input_data.txt", "w");
for(i = 0; i < N; i++)
{
in[i] = sin(2.0 * M_PI * (2.0 * M_PI * i/N));
fprintf(fd, "%f\n", in[i]);
}
fclose(fd);
fftwf_execute(plan);
fftwf_destroy_plan(plan);
fftwf_cleanup();
// Do in-place transform
for(i = 0; i < N/2 + 1; i++)
{
inplace[i] = out[i];
}
plan = fftwf_plan_dft_c2r_1d(N, (fftwf_complex *)inplace, (float *)inplace, FFTW_ESTIMATE);
// I think that I need to include the complex conjugates to the complex version of
// inplace (as this is what Mesinger does), and that's why we have the size of
// inplace being 2 * (N/2 + 1).
for(i = 1; i < N/2; i++)
{
inplace[N/2 + i] = conjf(inplace[N/2 - i]);
}
for(i = 0; i < 2 * (N/2 + 1); i++)
{
inplace[i] /= (float)N;
fftwf_execute(plan);
fftwf_destroy_plan(plan);
fftwf_cleanup();
fd = fopen("inplace_data.txt", "w");
for(i = 0; i < N; i++)
{
fprintf(fd, "%f\n", crealf(inplace[i]));
}
fclose(fd);
fftwf_free(in);
fftwf_free(out);
fftwf_free(inplace);
}
FFTW3のドキュメントから、実際のデータはサイズ2(N/2 + 1)でなければならないと言います。また、実際の複雑な変換は、エルミートの対称性のために複雑な配列の後半を切り捨てるので、これらの要素を明示的に入れなおすことにしましたが、必要かどうかはわかりません。私は、変換が正規化されていないと言いましたので、インプレース変換の出力をNで再調整しました。また、
for(i = 0; i < 2 * (N/2 + 1); i++)
{
inplace[i] /= (float)N;
}
fftwf_execute(plan);
fftwf_destroy_plan(plan);
fftwf_cleanup();
: