Q:

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

(Cross-posted from cython-users)
I am trying to use FFTW for some Cython code.  I am running into issues when trying to cast a pointer to a fftw_complex (a typedef to double[2]) to a complex memoryview, namely (minimal example)
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

fails at the cast: "hmm.pyx:8:34: Pointer base type does not match cython.array base type" (perhaps it can't be expected for Cython to know that double[2] can be converted to complex but... what else can I do?)
PS: If someone has experience using the pyFFTW wrapper directly from Cython, I'm interested too.
Thanks in advance.

A:

It's complaining that it the type of complex_ny isn't the same as complex (and it doesn't know the conversion). If you cast complex_ny to a complex* first, then assign the pointer to a memoryview it's happier:
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

As I'm sure you're aware, this only works because you've made it so that complex and fftw_complex are the same size.

Addendum
Given that fftw_complex and complex have exactly the same memory layout, the easiest solution is just to tell Cython that the fftw_ functions deal with complex* instead of fftw_complex*. It doesn't actually look at the C files to check this is true - it just uses it for type conversion and memory allocation (both of which it should be OK for)
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

(You do get a warning about incompatible pointer types during the C compilation step, but it's only a warning, and you know the types are actually compatible.)

