C 使用FFTW3的就地FFT

C 使用FFTW3的就地FFT,c,fftw,C,Fftw,我试图理解c中FFTW3的就地FFT和异地FFT。首先,我决定使用一维变换。我先做了不合适的实-实转换,然后使用转换的复杂输出进行了实-实转换,希望得到原始的实输入数据。然而,我不知道,我只是想知道为什么?下面是我的示例代码 #include <stdlib.h> #include <stdio.h> #include <complex.h> #include <fftw3.h> #include <math.h> void one_

我试图理解c中FFTW3的就地FFT和异地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);
}
#包括
#包括
#包括
#包括
#包括
void一维变换(void)
{
浮入;
fftwf_复合体*out,*in place;
int N=8;
fftwf_计划;
int i;
文件*fd;
//进行错位转换。为此,in有N个元素,out有N/2+1。
in=fftwf_alloc_real(N);
out=fftwf_alloc_复合体(N/2+1);
inplace=fftwf_alloc_复合体(2*((N/2)+1));
计划=fftwf_计划_dft_r2c_1d(N,输入,输出,FFTW_估算);
fd=fopen(“input_data.txt”,“w”);
对于(i=0;i

根据FFTW3文档,他们说实际数据的大小必须为2(N/2+1)此外,由于厄米对称性,实数到复数的变换会切断复数数组的后半部分,因此我决定显式地将这些元素放回,但我不确定是否需要。我还将就地变换的输出重新缩放了N,因为文档中说变换没有规范化。

主要问题是由于循环,发布的代码实际运行了多次
fftwf\u execute
(和
fftw\u destroy
!)

for(i = 0; i < 2 * (N/2 + 1); i++)
{   
    inplace[i] /= (float)N;
    fftwf_execute(plan);
    fftwf_destroy_plan(plan);
    fftwf_cleanup();
    ...
}
而不是仅使用
crealf(inplace[i])
提取真实零件(这只需要每秒一次的值)

最后,关于你的评论

此外,由于厄米对称性,实数到复数的变换会切断复数数组的后半部分,因此我决定显式地将这些元素放回,但我不确定是否需要这样做

我可以向你保证这是不需要的。复到实变换不需要光谱的后半部分,因为它是基于它具有厄米对称性的知识

for(i = 0; i < 2 * (N/2 + 1); i++)
{   
    inplace[i] /= (float)N;
}
fftwf_execute(plan);
fftwf_destroy_plan(plan);
fftwf_cleanup();
  for(i = 0; i < N; i++)
  {
    fprintf(fd, "%f\n", ((float*) inplace)[i]));
  }