复杂numpy数组上的FFTW3直接在scipy.weave.inline中

时间:2012-10-24 18:04:25

标签: python c numpy scipy fftw

我正在尝试在Python中实现基于FFT的子像素移位(转换)算法。傅立叶移位定理允许阵列通过以下子像素量转换:   1.正向FFT阵列   2.在傅立叶空间中通过线性相位斜坡乘以阵列   3.反FFT阵列

这个算法很容易在python中使用numpy / scipy实现,但是对于256 ** 2数组来说,它每转移速度非常慢(~10毫秒)。我试图通过使用scipy.weave.inline直接从python调用c代码来加快速度。

我在将复杂的numpy数组传递给FFTW时遇到了麻烦。 c代码如下:

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

    #define INVERSE +1
    #define FORWARD -1


    fftw_complex *i, *o;
    int n, m;
    fftw_plan pf, pi;
    #line 22 "test_scipy_weave.py" 

    i = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * xdim*ydim);
    o = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * xdim*ydim);

    pf = fftw_plan_dft_2d(xdim, ydim, i, o, -1, FFTW_PATIENT);
    pi = fftw_plan_dft_2d(xdim, ydim, o, i,  1, FFTW_PATIENT);

    # Copy data to fftw_complex array. How to use python arrays directly
    for (n=0; n<xdim;n++){
        for (m=0; m<ydim; m++){
            i[n*xdim+m][0]=a[n*xdim+m].real();
            i[n*xdim+m][1]=a[n*xdim+m].imag();
        }
    }

    fftw_execute(pf);

    /* Mult by linear phase ramp here */

    fftw_execute(pi);

    for (n=0; n<xdim;n++){
        for (m=0; m<ydim; m++){
            b[n*xdim+m] = std::complex<double>([in*xdim+m][0], i[n*xdim+m][1]);
        }
    }

    fftw_destroy_plan(p);

所以你可以看到我必须将存储在numpy数组“a”中的数据复制到fftw_complex数组“i”中。最后,我必须将结果“i”复制到输出numpy数组“b”中。在fftw中直接使用numpy数组“a”和“b”会更有效,但我无法使其工作。

有没有人知道如何让fftw直接在scipy.weave.inline中使用复杂的numpy数组?

由于

1 个答案:

答案 0 :(得分:0)

根据fftw manual,您可以在complex.h之前导入fftw.h,这将保证fftw_complex将与本机C数据类型相对应。我很确定numpy数据类型也保证(或实际上可能)与本机C数据类型兼容。

在这种情况下,您可以访问指向数组数据的指针a.data_as(ctypes.c_void_p)。不幸的是,ctypes无法识别复杂类型,但希望转换为void指针可以解决问题。

执行此操作时,必须注意数组a以C连续方式存储,在创建数组时由参数order='C'指定。