- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的大部分库都是在“正常”C 模式下用 Cython 编写的。到目前为止,我很少需要任何 C++ 功能,但总是假设(有时确实如此!)如果我愿意,我可以只为一个模块切换到 C++ 模式。
所以我有 10 多个 C 模式模块和 1 个 C++ 模式模块。
现在的问题是 Cython 似乎如何处理复数定义。在 C 模式下,它假设我认为是 C 复数,而在 C++ 模式下,它假设我认为是 C++ 复数。我读过它们现在甚至可能是相同的,但无论如何 Cython 提示它们不是:
openChargeState/utility/cheb.cpp:2895:35: error: cannot convert ‘__pyx_t_double_complex {aka std::complex<double>}’ to ‘__complex__ double’ for argument ‘1’ to ‘double cabs(__complex__ double)’
__pyx_t_5 = ((cabs(__pyx_v_num) == INFINITY) != 0);
在那种情况下,我尝试使用 C 模式模块中定义的出租车,并从 C++ 模式模块调用它。
我知道有一些明显的解决方法(现在我只是不使用 C++ 模式;我想使用向量,而不是现在使用较慢的 Python 列表)。
有没有办法告诉我的 C++ 模式模块使用 C 复数,或者告诉它它们是相同的?如果我在我的 C++ 模式模块中找不到 ctypedef C 复数的工作方法...或者是否有任何其他解决方案?
编辑: DavidW 和 ead 的评论提出了一些合理的建议。首先是最小工作示例。
设置.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
extra_compile_args=['-O3']
compdir = {'language_level' : '3'}
extensions = cythonize([
Extension("cmod", ["cmod.pyx"]),
Extension("cppmod", ["cppmod.pyx"], language='c++')
],
compiler_directives = compdir
)
setup(cmdclass = {'build_ext': build_ext},
ext_modules = extensions
)
import cppmod
cmod.pyx
cdef double complex c_complex_fun(double complex xx):
return xx**2
cmod.pxd
cdef double complex c_complex_fun(double complex xx)
cdef extern from "complex.h":
double cabs(double complex zz) nogil
cppmod.pyx
cimport cmod
cdef double complex cpp_complex_fun(double complex xx):
return cmod.c_complex_fun(xx)*abs(xx) # cmod.cabs(xx) doesn't work here
print(cpp_complex_fun(5.5))
然后用 python3 setup.py build_ext --inplace 编译。
现在有趣的部分是(如代码中所写)只有“间接”导入的 c 函数有问题,在我的例子中是 cabs。所以只使用 abs 的建议实际上确实有帮助,但我仍然不理解底层逻辑。我希望我不会在另一个问题中遇到这个问题。我暂时不提这个问题。也许有人知道发生了什么。
最佳答案
您的问题与以下事实无关:一个模块编译为 C 扩展,另一个模块编译为 C++ 扩展 - 仅在 C++ 扩展中即可轻松重现该问题:
%%cython -+
cdef extern from "complex.h":
double cabs(double complex zz) nogil
def cpp_complex_fun(double complex xx):
return cabs(xx)
导致您的错误消息:
error: cannot convert
__pyx_t_double_complex {aka
to
std::complex<double>}__complex__ double
for argument1
todouble cabs(__complex__ double)
问题是复数是……好吧,复数。 Cython 的策略(可以查找 here 和 here )处理复数是使用 C/CPP 的可用实现,如果没有找到,则使用手写回退:
#if !defined(CYTHON_CCOMPLEX)
#if defined(__cplusplus)
#define CYTHON_CCOMPLEX 1
#elif defined(_Complex_I)
#define CYTHON_CCOMPLEX 1
#else
#define CYTHON_CCOMPLEX 0
#endif
#endif
....
#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
如果是 C++ 扩展,Cython 的 double complex
翻译成std::complex<double>
因此不能用 cabs( double complex z )
调用因为std::complex<double>
不是 double complex
.
所以实际上,这是你的“错”:你对 Cython 撒谎并告诉他,cabs
有签名double cabs(std::complex<double> z)
,但这还不足以欺骗 c++ 编译器。
这意味着,在 c++ 模块中 std::abs(std::complex<double>)
可以使用,或者只是 Cython/Python 的 abs
,即 automatically translated到正确的功能(然而,这对所有标准功能来说都是不可能的)。
在 C 扩展的情况下,因为您包含了 complex.h
作为所谓的“早期包含”cdef extern from "complex.h"
,因此对于上述定义 _Complex_I
被定义并且 Cython 的复合体成为 double complex
的别名因此 cabs
可以使用。
对于 Cython 来说,正确的做法可能是始终默认使用回退,并且用户应该能够明确选择所需的实现(double complex
或 std::complex<double>
)。
关于cython - 如何在 'language=c++'模式下使用C复数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62106107/
对此感到疯狂,真的缺少一些东西。 我有webpack 4.6.0,webpack-cli ^ 2.1.2,所以是最新的。 在文档(https://webpack.js.org/concepts/mod
object Host "os.google.com" { import "windows" address = "linux.google.com" groups = ["linux"] } obj
每当我安装我的应用程序时,我都可以将数据库从 Assets 文件夹复制到 /data/data/packagename/databases/ .到此为止,应用程序工作得很好。 但 10 或 15 秒后
我在 cc 模式缓冲区中使用 hideshow.el 来折叠我不查看的文件部分。 如果能够在 XML 文档中做到这一点就好了。我使用 emacs 22.2.1 和内置的 sgml-mode 进行 xm
已结束。此问题不符合 Stack Overflow guidelines .它目前不接受答案。 我们不允许提出有关书籍、工具、软件库等方面的建议的问题。您可以编辑问题,以便用事实和引用来回答它。 关闭
根据java: public Scanner useDelimiter(String pattern) Sets this scanner's delimiting pattern to a patt
我读过一些关于 PRG 模式以及它如何防止用户重新提交表单的文章。比如this post有一张不错的图: 我能理解为什么在收到 2xx 后用户刷新页面时不会发生表单提交。但我仍然想知道: (1) 如果
看看下面的图片,您可能会清楚地看到这一点。 那么如何在带有其他一些 View 的简单屏幕中实现没有任何弹出/对话框/模式的微调器日期选择器? 我在整个网络上进行了谷歌搜索,但没有找到与之相关的任何合适
我不知道该怎么做,我一直遇到问题。 以下是代码: rows = int(input()) for i in range(1,rows): for j in range(1,i+1):
我想为重写创建一个正则表达式。 将所有请求重写为 index.php(不需要匹配),它不是以/api 开头,或者不是以('.html',或'.js'或'.css'或'.png'结束) 我的例子还是这样
MVC模式代表 Model-View-Controller(模型-视图-控制器) 模式 MVC模式用于应用程序的分层开发 Model(模型) - 模型代表一个存取数据的对象或 JAVA PO
我想为组织模式创建一个 RDF 模式世界。您可能知道,组织模式文档基于层次结构大纲,其中标题是主要的分组实体。 * March auxiliary :PROPERTIES: :HLEVEL: 1 :E
我正在编写一个可以从文件中读取 JSON 数据的软件。该文件包含“person”——一个值为对象数组的对象。我打算使用 JSON 模式验证库来验证内容,而不是自己编写代码。符合代表以下数据的 JSON
假设我有 4 张 table 人 公司 团体 和 账单 现在bills/persons和bills/companys和bills/groups之间是多对多的关系。 我看到了 4 种可能的 sql 模式
假设您有这样的文档: doc1: id:1 text: ... references: Journal1, 2013, pag 123 references: Journal2, 2014,
我有这个架构。它检查评论,目前工作正常。 var schema = { id: '', type: 'object', additionalProperties: false, pro
这可能很简单,但有人可以解释为什么以下模式匹配不明智吗?它说其他规则,例如1, 0, _ 永远不会匹配。 let matchTest(n : int) = let ran = new Rand
我有以下选择序列作为 XML 模式的一部分。理想情况下,我想要一个序列: 来自 my:namespace 的元素必须严格解析。 来自任何其他命名空间的元素,不包括 ##targetNamespace和
我希望编写一个 json 模式来涵盖这个(简化的)示例 { "errorMessage": "", "nbRunningQueries": 0, "isError": Fals
首先,我是 f# 的新手,所以也许答案很明显,但我没有看到。所以我有一些带有 id 和值的元组。我知道我正在寻找的 id,我想从我传入的三个元组中选择正确的元组。我打算用两个 match 语句来做到这
我是一名优秀的程序员,十分优秀!