Python scipy.fftpack.fft2和cuft之间的结果差异

Python scipy.fftpack.fft2和cuft之间的结果差异,python,numpy,cuda,fft,Python,Numpy,Cuda,Fft,现在,我正在将python脚本移植到CUDA程序。 在我的python脚本中,使用了scipy.fftpack.fft2。 为了验证cufft的结果,我使用cufft编写了示例程序。 然而,scipy.fftpack.fft2和cuft之间似乎存在差异 有什么建议吗 python脚本: def test2(): g = [18,19,19,23,24,24,23,24,24] g = numpy.array(g) g.shape = [3,3] G = fft2(g)

现在,我正在将python脚本移植到CUDA程序。 在我的python脚本中,使用了scipy.fftpack.fft2。 为了验证cufft的结果,我使用cufft编写了示例程序。 然而,scipy.fftpack.fft2和cuft之间似乎存在差异

有什么建议吗

python脚本:

def test2():
   g = [18,19,19,23,24,24,23,24,24]
   g = numpy.array(g)
   g.shape = [3,3]
   G = fft2(g)

   print "---------------"
   print g
   print G
   return 
   ---------------
    [[18 19 19]
     [23 24 24]
     [23 24 24]]
    [[ 198.+0.j   -3.+0.j   -3.+0.j]
     [ -15.+0.j    0.+0.j    0.+0.j]
     [ -15.+0.j    0.+0.j    0.+0.j]]
python脚本的结果:

def test2():
   g = [18,19,19,23,24,24,23,24,24]
   g = numpy.array(g)
   g.shape = [3,3]
   G = fft2(g)

   print "---------------"
   print g
   print G
   return 
   ---------------
    [[18 19 19]
     [23 24 24]
     [23 24 24]]
    [[ 198.+0.j   -3.+0.j   -3.+0.j]
     [ -15.+0.j    0.+0.j    0.+0.j]
     [ -15.+0.j    0.+0.j    0.+0.j]]
cuda计划:

        cufftHandle plan;
        int nRows = 3;
        int nCols = 3;
        cufftPlan2d(&plan, nRows, nCols, CUFFT_R2C);
        float h_in[9] = {18,19,19,23,24,24,23,24,24};
        float* d_in;
        cudaMalloc(&d_in, sizeof(cufftComplex)*9); 
        cufftComplex* d_freq;
        cudaMalloc(&d_freq, sizeof(cufftComplex)*9); 
        cudaMemcpy(d_in,h_in,sizeof( cufftComplex)*9,cudaMemcpyHostToDevice);
        cufftExecR2C(inverse_plan, d_in, d_freq);
        cufftComplex* h_freq = (float2*)malloc(sizeof( cufftComplex)*9);    
        cudaMemcpy(h_freq,d_freq,sizeof( cufftComplex)*9,cudaMemcpyDeviceToHost);
        for(int i=0; i<9; i++) {
        printf("%i %f %f\n", i, h_freq[i].x, h_freq[i].y);
        }
0 198.000000 -0.000001
1 -2.999996 -0.000001
2 -15.000000 0.000000
3 -0.000000 0.000000
4 -15.000000 0.000000
5 -0.000000 0.000000
6 497922732955248410000000000000.000000 8589934592.000000
7 572199135312371230000000000000.000000 8589934592.000000
8 -0.000000 0.000000

我不是cufft专家,但这种命名方式透露出发生了什么:

  • 在numpy中,您正在运行完整的2D FFT。因为您的输入是实的,所以输出是对称的,如您所见:每行(或每列)中的最后一项与前一项相等

  • 您可以利用这一点更快地运行FFT,在numpy中,这是通过
    rfft2
    功能实现的:

    >>> np.fft.rfft2(g)
    array([[ 198.+0.j,   -3.+0.j],
           [ -15.+0.j,    0.+0.j],
           [ -15.+0.j,    0.+0.j]])
    
  • 我的猜测是,您的
    CUFFT\u R2C
    计划名称中的
    R2C
    表示“从真实到复杂”,因此您要求的是与
    np.rfft2
    等效的名称。如果将数组中未使用的最后3项放在一边,除了舍入错误和CUDA实现使用32位浮点,而不是numpy默认使用的64位浮点,结果几乎相同

  • 快速的谷歌搜索显示
    CUFFT_C2C
    cufftExecR2C
    是有效的CUFFT标识符。使用这些应该会产生你想要的正确结果。为了更接近复制,重构您的代码并使用
    Z2Z
    版本,它使用的是
    double
    ,而不是
    float


感谢您的回答。我确认CUFFT_R2C的结果与numpy.rfft2几乎相同。CUFFT_R2C和numpy.rfft2之间的细微差异可能是由于计算错误或浮点类型(float32或float64)造成的。@jurader如果这回答了您的问题,则习惯于接受答案。您可以通过单击答案投票按钮下方的复选标记按钮来执行此操作。