简体   繁体   English

直接在scipy.weave.inline中对复杂的numpy数组进行FFTW3

[英]FFTW3 on complex numpy array directly in scipy.weave.inline

I am trying to implement an FFT based subpixel shifting (translation) algorithm in Python . 我正在尝试在Python实现基于FFT的子像素移位(平移)算法。 The Fourier shift theorem allows an array to be translated by a subpixel amount by: 1. Forward FFT array 2. Multiply array by linear phase ramp in Fourier space 3. Inverse FFT array 傅里叶移位定理允许通过以下方式将阵列转换一个亚像素量:1.正向FFT阵列2.傅立叶空间中的线性相位斜率乘以阵列3.逆FFT阵列

This algorithm is easy to implement in python using numpy/scipy but its incredibly slow (~10msec) per shift for 256**2 array. 这个算法很容易在python中使用numpy / scipy来实现,但是对于256 ** 2数组,它的每移位非常慢(〜10毫秒)。 I am trying to speed this up by calling c code directly from python using scipy.weave.inline. 我试图通过使用scipy.weave.inline直接从python调用c代码来加快速度。

I'm having trouble however in passing complex numpy arrays to FFTW. 但是在将复杂的numpy数组传递给FFTW时遇到了麻烦。 The c code looks like: 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);

So you can see I have to copy the data stored in the numpy array "a" into the fftw_complex array "i". 因此,您可以看到我必须将存储在numpy数组“ a”中的数据复制到fftw_complex数组“ i”中。 And again at the end I have to copy the result "i" into the output numpy array "b". 最后,我必须再次将结果“ i”复制到输出numpy数组“ b”中。 It would be much more efficient to use the numpy arrays "a" and "b" directly in the fftw but I cannot get this to work. 直接在fftw中使用numpy数组“ a”和“ b”会更有效,但我无法使它起作用。

Does anyone have an idea on how to get fftw to use complex numpy arrays directly in scipy.weave.inline ? 有谁知道如何让scipy.weave.inline直接在scipy.weave.inline使用复杂的numpy数组?

Thanks 谢谢

According to the fftw manual , you can import complex.h before fftw.h , which will guarantee that fftw_complex will correspond to the native C data type. 根据fftw.h 手册 ,您可以在fftw.h之前导入complex.h ,这将确保fftw_complex将对应于本机C数据类型。 I'm pretty sure that numpy data types are also guaranteed to be (or in practice are likely to be) compatible with native C data types. 我很确定numpy数据类型也可以保证与本机C数据类型兼容(或在实践中很可能兼容)。

In this case you can access a pointer to the array data as a.data_as(ctypes.c_void_p) . 在这种情况下,您可以使用a.data_as(ctypes.c_void_p)访问指向数组数据的指针。 Unfortunately ctypes doesn't recognise complex types, but hopefully casting to a void pointer will do the trick. 不幸的是,ctypes无法识别复杂类型,但是希望强制转换为void指针可以解决问题。

When doing this, you have to be careful that your array a is stored in C-contiguous fashion, specified by the parameter order='C' when creating the array. 这样做时,您必须注意,数组a以C连续方式存储,在创建数组时由参数order='C'指定。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM