Cython中的abs(双复合物)

2024-09-27 00:21:52 发布

您现在位置:Python中文网/ 问答频道 /正文

如何获得double complex变量的绝对值?在

def f():
    cdef double complex aaa = 1 + 2j
    cdef double bbb = abs(aaa)

第二个赋值在cython -ahtml输出中突出显示为黄色:aaa在应用abs()之前被转换为python对象。在

如何在c/cpp级别调用abs()?在

PS我明白

^{pr2}$

会解决它,但我在生成的c/cpp文件中看到以下说明:

#if CYTHON_CCOMPLEX
        #define __Pyx_c_abs_double(z)     (::std::abs(z))
#endif

类似的,它应该根据编译标志选择正确的头来包含(<complex>或{}或自定义代码)。在

如何使用这些说明?在


Tags: 对象defabs级别cppcythonpsdouble
1条回答
网友
1楼 · 发布于 2024-09-27 00:21:52

更多有用的贡献

下面是对修复“cython/compiler”的半测试添加/内置.py". 在哪里添加它应该非常明显:

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)),

它似乎起作用了。它还没有通过完整的Cython测试套件。它还不能在文件的顶部生成正确的代码(但可能不需要,因为您已经使用了complex double),而实际上是这样。它还不能在nogil块中工作。在

一旦我研究了这些问题,我可能会把它提交给cythongithub。在


原始答案:

由于Cython尝试使用复杂类型的“原生”布局,整个过程变得稍微复杂一些。根据Cython生成的代码:

^{pr2}$

在所有的情况下,类型都应该有一个兼容的内存布局(我认为),所以最坏的情况是一点类型转换应该允许您使用任何实现的abs函数。在

更令人困惑的是,如果您查看生成的Cython代码(在生成的文件中搜索各种#if CYTHON_CCOMPLEX块),就会发现Cython为所有这些类型定义了abs的快速版本(以及其他有用的函数),但未能智能地使用它们,这又回到了Python实现中。在

如果你要通过C,你需要告诉Cython关于cabs来自{}:

cdef extern from "complex.h":
    double cabs(double complex)

def f():
    cdef double complex aaa = 1 + 2j
    cdef double bbb = cabs(aaa)
    return bbb

如果你正在通过C++,你需要告诉Cython关于C++标准库^ {CD3>}。不幸的是,它无法在其预定义包装器中的libcpp.complex.complexdouble complex类型之间建立链接,因此您需要自己告诉它有关函数的信息:

cdef extern from "<complex>":
    double abs(double complex)

def f():
    cdef complex aaa = 1 + 2j
    cdef double bbb = abs(aaa)
    return bbb

如果CYTHON_CCOMPLEX没有定义,我不知道该怎么做,但是我认为无论如何,这是必须显式地做的事情。在

相关问题 更多 >

    热门问题