2

In Cython, starting from a C++ vector of std::complex<double> like this...

# Imports 
from libcpp.vector cimport vector
from libcpp.complex cimport complex as cpp_complex
ctypedef my_complex = cpp_complex[double]

# Code
cdef vector[my_complex] vec

... how can I convert this vector to a double complex memoryview with the default cython/python's complex?

cdef complex[::1] mem_view = ???

Alternatively, how can I tell Cython to use C++'s std::complex<double> instead of double complex as the underneath type of complex?

ibarrond
  • 6,617
  • 4
  • 26
  • 45

1 Answers1

2

It suffices to extract a pointer to the data with vec.data() (returns a complex[double]*), cast it to cython complex*, and cast the array to the fixed vector size:

cdef complex[::1] mem_view = <complex[:vec.size()]>(<complex*>vec.data())

For the alternative (setting std::complex<double> | cython's cpp_complex[double] to be the standard complex type), one would have to add some defines to trigger the choice in https://github.com/cython/cython/blob/master/Cython/Utility/Complex.c#L56. However, I'm not sure how to do that.

ibarrond
  • 6,617
  • 4
  • 26
  • 45
  • Note: an answer with better explanations or showing the alternative will be marked as right answer! – ibarrond Sep 02 '21 at 13:08
  • Note2: to return a numpy array, just do `np.asarray(mem_view)`. – ibarrond Sep 02 '21 at 14:31
  • This is probably the right answer. To set the c define you'd use [`extra_compile_flags`](https://stackoverflow.com/questions/33520619/extra-compile-args-in-cython). On Linux this'd be `-DCYTHON_CCOMPLEX=0` (or 1). Note that it's on by default and only affects the C++ compilation stage so you still need the casts in Cython. – DavidW Sep 04 '21 at 10:30
  • I had the feeling it was like this, the error was raised when `cythonize` was called, meaning that the C++ compiler is not yet involved in it. Good to know! – ibarrond Sep 05 '21 at 10:37