Difference between complex.real and creal (complex) in Cython

To separate the real part of the complex parts in cython, I usually use complex.realand complex.imagfor the job. However, it generates code colored in red "python red" in html-output, and I assume that I should use creal(complex)and instead cimag(complex).

Consider the example below:

cdef double complex myfun():
    cdef double complex c1,c2,c3
    c1=1.0 + 1.2j
    c2=2.2 + 13.4j
    c3=c2.real + c1*c2.imag
    c3=creal(c2) + c1*c2.imag
    c3=creal(c2) + c1*cimag(c2)
    return c2

Adaptations to c3give:

__pyx_v_c3 = __Pyx_c_sum(__pyx_t_double_complex_from_parts(__Pyx_CREAL(__pyx_v_c2), 0), __Pyx_c_prod(__pyx_v_c1, __pyx_t_double_complex_from_parts(__Pyx_CIMAG(__pyx_v_c2), 0)));

__pyx_v_c3 = __Pyx_c_sum(__pyx_t_double_complex_from_parts(creal(__pyx_v_c2), 0), __Pyx_c_prod(__pyx_v_c1, __pyx_t_double_complex_from_parts(__Pyx_CIMAG(__pyx_v_c2), 0)));

__pyx_v_c3 = __Pyx_c_sum(__pyx_t_double_complex_from_parts(creal(__pyx_v_c2), 0), __Pyx_c_prod(__pyx_v_c1, __pyx_t_double_complex_from_parts(cimag(__pyx_v_c2), 0)));

where the first line is used to build the (python colored) construct __Pyx_CREALand __Pyx_CIMAG.

Whys it, and does it have a big impact on performance?

+4
source share
2 answers

, C (complex.h) .

, , - c.real c.imag. with nogil:, , API- Python:

cdef double complex c1, c2, c3
with nogil:
    c1 = 1.0 + 1.2j
    c2 = 2.2 + 13.4j
    c3 = c2.real + c1*c2.imag

Windows 7 Python 2.7, complex.h, C Visual Studio 9.0 ( Python 2.7). - , c.real c.imag:

cdef double mycreal(double complex dc):
    cdef double complex* dcptr = &dc
    return (<double *>dcptr)[0]

cdef double mycimag(double complex dc):
    cdef double complex* dcptr = &dc
    return (<double *>dcptr)[1]

:

def myfun1(double complex c1, double complex c2):
    return c2.real + c1*c2.imag

def myfun2(double complex c1, double complex c2):
    return mycreal(c2) + c1*mycimag(c2)

:

In [3]: timeit myfun1(c1, c2)
The slowest run took 17.50 times longer than the fastest. This could mean that a
n intermediate result is being cached.
10000000 loops, best of 3: 86.3 ns per loop

In [4]: timeit myfun2(c1, c2)
The slowest run took 17.24 times longer than the fastest. This could mean that a
n intermediate result is being cached.
10000000 loops, best of 3: 87.6 ns per loop

, c.real c.imag .

+2

- : __Pyx_CREAL(c) __Pyx_CIMAG(c) , / :

#if CYTHON_CCOMPLEX
  #ifdef __cplusplus
    #define __Pyx_CREAL(z) ((z).real())
    #define __Pyx_CIMAG(z) ((z).imag())
  #else
    #define __Pyx_CREAL(z) (__real__(z))
    #define __Pyx_CIMAG(z) (__imag__(z))
  #endif
#else
    #define __Pyx_CREAL(z) ((z).real)
    #define __Pyx_CIMAG(z) ((z).imag)
#endif

, :

  • std::complex<>.real() std::complex<>.imag(), ++.
  • GNU __real__ __imag__, gcc intel ( Intel ​​ ).

, . glibc, creal __real__. , Microsoft (CYTHON_CCOMPLEX ), / cython:

#if CYTHON_CCOMPLEX
  ....
#else
    static CYTHON_INLINE {{type}} {{type_name}}_from_parts({{real_type}} x, {{real_type}} y) {
      {{type}} z;
      z.real = x;
      z.imag = y;
      return z;
    }
#endif

, , , . , , , Windows ( , ).

: gcc/intel, .

+2

Source: https://habr.com/ru/post/1686195/


All Articles