gpt4 book ai didi

python - Cython 中的 abs(双复合体)

转载 作者:太空宇宙 更新时间:2023-11-03 15:26:54 26 4
gpt4 key购买 nike

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

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

第二个作业在cython -a中以黄色突出显示。 html 输出:aaa在应用 abs() 之前转换为 python 对象.

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

PS我明白了

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

可以解决这个问题,但我在生成的 c/cpp 文件中看到以下说明:

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

等等,应该根据编译标志选择要包含的正确 header (<complex>"complex.h"或自定义代码)。

我如何利用这些说明?

最佳答案

更有用的贡献:

以下是修复“cython/compiler/Builtin.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 中工作。 block 。

一旦我查看了这些问题,我可能会将其提交到 Cython github。

<小时/>

原始答案:

由于 Cython 尝试使用复杂类型的“ native ”布局,整个事情变得稍微复杂一些。从 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

在所有情况下,类型都应该具有兼容的内存布局(我认为),所以最坏的情况是,一些类型转换应该让您使用任何实现的 abs功能。

为了增加困惑,如果您查看生成的 Cython 代码(搜索生成文件中的各个 #if CYTHON_CCOMPLEX block ),Cython 似乎定义了 abs 的快速版本(以及其他有用的函数)适用于所有这些类型,但无法智能地使用它们,而是退回到 Python 实现。

如果您要使用 C,则需要告诉 Cython cabs来自complex.h :

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++ 标准库的信息 abs 。不幸的是,它无法在 libcpp.complex.complex 之间建立链接。在其预定义的包装器和 double 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 我不知道该怎么办未定义,但我认为无论如何您都必须明确执行此操作。

关于python - Cython 中的 abs(双复合体),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43067131/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com