我正在用 cython 逐个元素构建一个数组。我想在某些条目中存储常量
np.inf
(或 -1 * np.inf
)。然而,这将需要返回 Python 来查找 inf
的开销。是否存在与该常数等价的 libc.math
?或者其他一些可以轻松使用的值,相当于 (-1*np.inf)
并且可以在 Cython 中使用而无需开销?
编辑示例,您有:
cdef double value = 0
for k in xrange(...):
# use -inf here -- how to avoid referring to np.inf and calling back to python?
value = -1 * np.inf
在 Cython 中执行此操作的推荐方法是:
from numpy.math cimport INFINITY
请注意,这是“cimport”而不是常规导入。这是 Cython 对 NumPy 的
npymath
的官方包装。
它没有文字,但是
float
可以从字符串中解析它:
>>> float('inf')
inf
>>> np.inf == float('inf')
True
或者,
math.h
可能(几乎肯定会)声明一个计算结果为inf的宏,在这种情况下你可以使用它:
cdef extern from "math.h":
float INFINITY
(没有干净的方法来检查 INFINITY 是否在纯 Cython 中定义,所以如果你想覆盖所有基础,你需要 hacky。一种方法是创建一个小的 C 标头,比如
fallbackinf.h
:
#ifndef INFINITY
#define INFINITY 0
#endif
然后在你的 .pyx 文件中:
cdef extern from "math.h":
float INFINITY
cdef extern from "fallbackinf.h":
pass
inf = INFINITY if INFINITY != 0 else float('inf')
(您不能分配给 INFINITY,因为它是一个右值。如果您在标头中将 INFINITY #define 为 1.0/0.0,则可以取消三元运算符,但这可能会引发 SIGFPE,具体取决于您的编译器。)
不过,这绝对属于货物崇拜优化领域。)
您可以使用 Numpy 的数学库,请参阅此处了解可用内容:
cdef extern 来自“numpy/npy_math.h”: 双 inf“NPY_INFINITY”
构建 Cython 扩展模块时,需要指定正确的包含目录和要链接的库:
>>> 来自 numpy.distutils.misc_util 导入 get_info >>> get_info('npymath') {'define_macros':[], '库':['npymath','m'], 'library_dirs': ['/usr/lib/python2.7/dist-packages/numpy/core/lib'], 'include_dirs': ['/usr/lib/python2.7/dist-packages/numpy/core/include']}
从该函数获得的信息可以传递到 Python distutils 或您使用的任何构建系统。
在 C99 之前,连 C 都不支持这个,所以 Cython 没有任何选择。
从C99开始:
from libc.math cimport INFINITY
cdef double f():
return INFINITY
请参阅 Cython 源代码 https://github.com/cython/cython/blob/master/Cython/Includes/libc/math.pxd