Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Cython中complex.real和creal(complex)之间的差异_Python_Cython_Complex Numbers_Complextype - Fatal编程技术网

Python Cython中complex.real和creal(complex)之间的差异

Python Cython中complex.real和creal(complex)之间的差异,python,cython,complex-numbers,complextype,Python,Cython,Complex Numbers,Complextype,在cython中,为了将真实部分与复杂部分分开,我通常使用complex.real和complex.imag来完成这项工作。然而,这确实会生成在html-输出中被涂成轻微“python红色”的代码,我想我应该使用creal(complex)和cimag(complex) 考虑下面的示例: cdef double complex myfun(): cdef double complex c1,c2,c3 c1=1.0 + 1.2j c2=2.2 + 13.4j c3

在cython中,为了将真实部分与复杂部分分开,我通常使用
complex.real
complex.imag
来完成这项工作。然而,这确实会生成在
html
-输出中被涂成轻微“python红色”的代码,我想我应该使用
creal(complex)
cimag(complex)

考虑下面的示例:

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
c3
的分配给出:

\uuuuPyx_v_c3=\uuPyx_c_c1(\uuuPyx_t_Udouble_Ucomplex_Ufrom_uparts(\uuPyx_v_c2),0),\uPyx_c_c_c1(\uuuPyx_v_c1,\uuuPyx_Udouble_Ucomplex_Ufrom_Uparts(\uPyx_CIMAG,0)),0)

\uuuupyx\uv\uC3=\uuupyx\uC\uSum(\uuupyx\uT\uDouble\uComplex\uU from_uParts(creal(\uupyx\uV\uC2),0),\uupyx\uC\uProduct(\uupyx\uV\uC1,\uuuuuupyx\uT\uDouble\uU complex\u from_uuparts(\uuuuupyx\uCimag(\upyx\uV\uC2)),0))

\uuuupyx\uv\uc3=\uuupyx\uc\u和(\uuuupyx\ut\udouble\ucomplex\uu来自各部分(creal(\uuuupyx\uv\uc2),0),\uuupyx\uc\uprod(\uuuupyx\uv\uc1,\uuuuuuupyx\udouble\u complex\u来自各部分(cimag(\upyx\uv\uc2),0))

其中第一行使用(python颜色的)构造
\uuupyx\ucreal
\uupyx\ucimag


这是为什么?它是否“显著”影响性能?

当然是默认的C库 ()行得通 给你

然而,这个库似乎不会给您带来任何显著的改进 与
c.real
c.imag
方法相比。通过将代码放入
使用nogil:
块,您可以检查您的代码是否已经不调用 Python API:

cdef double complex c1, c2, c3
with nogil:
    c1 = 1.0 + 1.2j
    c2 = 2.2 + 13.4j
    c3 = c2.real + c1*c2.imag
我使用Windows7和Python2.7,这两个版本中没有可用的
complex.h
Visual Studio编译器9.0的内置C库(与Python 2.7兼容)。 因此,我创建了一个等价纯C函数来检查任何可能的 与
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]
得到了时间安排:

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
已经足够快了。

事实上,你不应该期望看到任何区别:
\uuupyx\ucreal(c)
\uuupyx\ucimag(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::Fielal.Real.(/<)/<代码>和<>代码:STD:::COMPUTION IMAGE()/CUT>(如果是C++)/LI>
  • \uuuuu real\uuuuu
    \uuuuu imag\uuuuu
    ,如果是gcc或英特尔编译器(英特尔不久前添加了支持)
  • 你无法打败它,例如,
    creal
    使用
    \uuuu real\uuuu
    。剩下的是Microsoft编译器(
    CYTHON\u CCOMPLEX
    未定义),用于:

    #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编译器没有区别,我不会为其他编译器的区别而烦恼太久

    #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