如何用numpy在Cython中表示inf或-inf?

问题描述 投票:0回答:4

我正在用 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
python optimization numpy scipy cython
4个回答
21
投票

在 Cython 中执行此操作的推荐方法是:

from numpy.math cimport INFINITY

请注意,这是“cimport”而不是常规导入。这是 Cython 对 NumPy 的

npymath
的官方包装。


18
投票

它没有文字,但是

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,具体取决于您的编译器。)

不过,这绝对属于货物崇拜优化领域。)


4
投票

您可以使用 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 或您使用的任何构建系统。


0
投票

在 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

© www.soinside.com 2019 - 2024. All rights reserved.