python - abs(double complex) in Cython -
how absolute value double complex
variable?
def f(): cdef double complex aaa = 1 + 2j cdef double bbb = abs(aaa)
the second assignment highlighted yellow in cython -a
html output: aaa
converted python object prior applying abs()
.
how call abs()
on c/cpp level?
ps understand
cdef extern "complex.h": double abs(double complex)
would solve it, see following instructions in generated c/cpp file:
#if cython_ccomplex #define __pyx_c_abs_double(z) (::std::abs(z)) #endif
and like, supposed choose correct header include (<complex>
or "complex.h"
or custom code) depending on compilation flags.
how utilize instructions?
more useful contribution:
the following semi-tested addition fix "cython/compiler/builtin.py". should pretty obvious add it:
builtinfunction('abs', none, none, "__pyx_c_abs{0}".format(pyrextypes.c_double_complex_type.funcsuffix), #utility_code = utilitycode.load('arithmetic', 'complex.c', pyrextypes.c_double_complex_type._utility_code_context()), func_type = pyrextypes.cfunctype( pyrextypes.c_double_type, [ pyrextypes.cfunctypearg("arg", pyrextypes.c_double_complex_type, none) ], is_strict_signature = true)), builtinfunction('abs', none, none, "__pyx_c_abs{0}".format(pyrextypes.c_float_complex_type.funcsuffix), #utility_code = utilitycode.load('arithmetic', 'complex.c', pyrextypes.c_float_complex_type._utility_code_context()), func_type = pyrextypes.cfunctype( pyrextypes.c_float_type, [ pyrextypes.cfunctypearg("arg", pyrextypes.c_float_complex_type, none) ], is_strict_signature = true)), builtinfunction('abs', none, none, "__pyx_c_abs{0}".format(pyrextypes.c_longdouble_complex_type.funcsuffix), #utility_code = utilitycode.load('arithmetic', 'complex.c', pyrextypes.c_longdouble_complex_type._utility_code_context()), func_type = pyrextypes.cfunctype( pyrextypes.c_longdouble_type, [ pyrextypes.cfunctypearg("arg", pyrextypes.c_longdouble_complex_type, none) ], is_strict_signature = true)),
it appears work. hasn't been run through full cython test-suite. doesn't yet generate correct code @ top of file(but shouldn't need since use complex double
does). doesn't yet work in nogil
block.
i'll submit cython github once i've looked @ these issues.
original answer:
the whole thing made more complicated since cython attempts use "native" layout complex type. code generated cython:
#if cython_ccomplex #ifdef __cplusplus typedef ::std::complex< double > __pyx_t_double_complex; #else typedef double _complex __pyx_t_double_complex; #endif #else typedef struct { double real, imag; } __pyx_t_double_complex; #endif
in cases types should have compatible memory layout (i think), worst case bit of type casting should let use implementation's abs
function.
to add confusion, if @ generated cython code (search through various #if cython_ccomplex
blocks in generated file) appears cython defines fast versions of abs
(and other useful functions) these types, fails use them intelligently, falling python implementation.
if you're going through c need tell cython cabs
complex.h
:
cdef extern "complex.h": double cabs(double complex) def f(): cdef double complex aaa = 1 + 2j cdef double bbb = cabs(aaa) return bbb
if you're going through c++ need tell cython c++ standard library abs
. unfortunately it's unable make link between libcpp.complex.complex
in predefined wrapper , double complex
type, need tell function yourself:
cdef extern "<complex>": double abs(double complex) def f(): cdef complex aaa = 1 + 2j cdef double bbb = abs(aaa) return bbb
i don't know if cython_ccomplex
isn't defined, think that's you'd have explicitly anyway.
Comments
Post a Comment