How do I get an absolute value for a double complex
variable?
def f():
cdef double complex aaa = 1 + 2j
cdef double bbb = abs(aaa)
The second assignment is highlighted yellow in cython -a
html output: aaa
is converted to python object prior to applying abs()
.
How do I call abs()
on c/cpp level?
PS I understand that
cdef extern from "complex.h":
double abs(double complex)
would solve it, but I see the following instructions in the generated c/cpp file:
#if CYTHON_CCOMPLEX
#define __Pyx_c_abs_double(z) (::std::abs(z))
#endif
and the like, which is supposed to choose the correct header to include (<complex>
or "complex.h"
or custom code) depending on the compilation flags.
How do I utilize those instructions?
More useful contribution:
The following is semi-tested addition to fix "cython/compiler/Builtin.py". It should be pretty obvious where to add it:
It appears to work. It hasn't been run through the full Cython test-suite. It doesn't yet generate the correct code at the top of your file(but probably shouldn't need to since you already use
complex double
which does). It doesn't yet work in anogil
block.I'll probably submit it to Cython github once I've looked at these issues.
Original Answer:
The whole thing is made slightly more complicated since Cython attempts to use the "native" layout for the complex type. From the code generated by Cython:
In all cases the types should have a compatible memory layout (I think), so the worst case is that a bit of type casting should let you use any implementation's
abs
function.To add to the confusion, if you look at the generated Cython code (search through the various
#if CYTHON_CCOMPLEX
blocks in the generated file) it appears that Cython defines fast versions ofabs
(and other useful functions) for all these types, but fails to use them intelligently, falling back to the Python implementation.If you're going through C you need to tell Cython about
cabs
fromcomplex.h
:If you're going through C++ you need to tell Cython about the C++ standard library
abs
. Unfortunately it's unable to make the link between thelibcpp.complex.complex
in its predefined wrapper and thedouble complex
type, so you need to tell it about the function yourself:I don't immediately know what to do if
CYTHON_CCOMPLEX
isn't defined, but I think that's something you'd have to do explicitly anyway.