FFTW 计划 rountine returns 返回 null

FFTW plan rountine returns back null

我需要有使用经验的人 FFTW

我正在编写一个需要进行实数到复数转换的程序,但我的计划例程 returns 返回 null,我不确定为什么。我正在为大小传递有效的整数参数,为数组传递非 NULL 指针。我查阅了文档,但它只说如果它不能使计划成为 returns NULL,但除了与我上面提到的相反,它没有列出我的计划失败的任何其他原因。下面是一段示例代码

int size ={64, 128, 256};

float *spatial = malloc(size[1]*size[1]*sizeof(float));
fftwf_complex *fourier = fftwf_alloc_complex(size[1]*size[1]);

for(int i=0; i< size[1]; i++){
    for(int j=0; j<size[1]; j++){
        spatial = //fill spatial array;
    }
}

for(int i=0; i< size[1]; i++){
    for(int j=0; j<size[1]; j++){
        fourier = //fill fourier array;
    }
}

fftwf_plan plan = fftwf_plan_dft_r2c_2d(size[1], size[1], spatial, fourier, FFTW_FORWARD);
fftwf_execute(plan);

fftwf_plan_dft_r2c_2d() 不断 returns 为 plan 返回 NULL,我不确定为什么

注意:我正在使用 Windows 8.1 和 Visual Studios 2012

我能够在 ubuntu 上重现您的问题... 问题来自 fftwf_plan_dft_r2c_2d 使用的标志 FFTW_FORWARD。我不知道它在哪里记录,但它不起作用。原因是 fftwf_plan_dft_r2c_2d 总是正向变换,反向变换是 fftwf_plan_dft_c2r_2d

此外,您还可以减少程序的内存占用。事实上,在 r2c 变换的情况下,只有一半的复数系数被计算和存储。因此,由 fftwf_alloc_complex(size[1]*size[1]); 分配的数组大约是所需大小的两倍。查看 the documentation 了解更多关于额外填充和频率布局的信息。

这里是gcc main.c -o main -lfftw3f -lm -std=c99编译的程序(在你的电脑上可能不同...)。标志 FFTW_FORWARDFFTW_ESTIMATE 替换。而#include <complex.h>放在#include <fftw3.h>之前,这样fftw就可以使用complex.h

的float复数类型
#include <complex.h>

#include <fftw3.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>


int main(int argc, char* argv[]){
    int size [3] ={64, 128, 256};

    float *spatial = malloc(size[1]*size[1]*sizeof(float));
    if(spatial==NULL){fprintf(stderr,"malloc failed\n");exit(1);}
    fftwf_complex *fourier = fftwf_alloc_complex(size[1]*(size[1]/2+1));
    if(fourier==NULL){fprintf(stderr,"fftwf_alloc_complex failed\n");exit(1);}
    for(int i=0; i< size[1]; i++){
        for(int j=0; j<size[1]; j++){
            spatial[i*size[1]+j] =1; //fill spatial array;
        }
    }

    for(int i=0; i< size[1]; i++){
        for(int j=0; j<(size[1]/2+1); j++){
            fourier[i*(size[1]/2+1)+j]  =2.0+I ;//fill fourier array;
        }
    }

    fftwf_plan plan = fftwf_plan_dft_r2c_2d(size[1], size[1], spatial, fourier, FFTW_ESTIMATE);

    if(plan==NULL){printf("fftwf_plan_dft_r2c_2d : big problem %d\n",size[1]);fflush(stdout);}
    fftwf_execute(plan);


    printf("average is %g\n",creal(fourier[0])/(size[1]*size[1]));

    fftwf_destroy_plan(plan);
    free(fourier);
    free(spatial);

    return 0;
}