将 fftw_complex 指针(aka double[2])投射到 cython 复杂内存视图

Casting fftw_complex pointer (aka double[2]) to cython complex memoryview

(从 cython 用户交叉发布)

我正在尝试将 FFTW 用于某些 Cython 代码。当我试图将指向 fftw_complex(double[2] 的类型定义)的指针转换为复杂的内存视图时,我 运行 遇到了问题,即(最小示例)

cdef extern from "fftw3.h":
    ctypedef double fftw_complex[2]
    fftw_complex* fftw_alloc_complex(int N)

cdef foo(complex[::1] input):
    complex_ny = fftw_alloc_complex(input.size)
    (<complex[:self.ny]>complex_ny)[:] = input
    # actual call to FFTW follows

转换失败:"hmm.pyx:8:34: Pointer base type does not match cython.array base type"(也许不能指望 Cython 知道 double[2] 可以转换为复数但是......我还能做什么?)

PS:如果有人有直接从 Cython 使用 pyFFTW 包装器的经验,我也很感兴趣。

提前致谢。

它抱怨 complex_ny 的类型与 complex 的类型不同(并且它不知道转换)。如果您先将 complex_ny 转换为 complex*,然后将指针分配给内存视图,它会更快乐:

complex_ny = fftw_alloc_complex(input.size)
cdef complex[::1] view_of_complex_ny = <complex[:input.size]>(<complex*>complex_ny)
view_of_complex_ny[:] = input

我相信您已经知道,这之所以有效,是因为您已经做到 complexfftw_complex 大小相同。


附录

鉴于 fftw_complexcomplex 具有完全相同的内存布局,最简单的解决方案就是告诉 Cython fftw_ 函数处理 complex* 而不是fftw_complex*。它实际上并没有查看 C 文件来检查这是真的 - 它只是将它用于类型转换和内存分配(两者都应该没问题)

cdef extern from "fftw3.h":
    complex* fftw_alloc_complex(int N)

def foo(complex[::1] input):
    cdef complex[::1] complex_ny
    complex_ny = <complex[:input.size]>fftw_alloc_complex(input.size)
    complex_ny[:] = input

(在 C 编译步骤中您确实收到了关于不兼容指针类型的警告,但这只是一个警告,您知道这些类型实际上是兼容的。)