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

时间:2013-04-17 02:44:31

标签: python optimization numpy scipy cython

我正在逐个元素地构建一个带有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

3 个答案:

答案 0 :(得分:14)

没有文字,但float可以从字符串中解析它:

>>> float('inf')
inf
>>> np.inf == float('inf')
True

或者,math.h 可能(几乎肯定会)声明一个评估为inf的宏,在这种情况下你可以使用它:

cdef extern from "math.h":
    float INFINITY

(没有干净的方法来检查INFINITY是否在纯Cython中定义,所以如果你想覆盖所有基础,你需要得到hacky。一种方法是创建一个小的C头,比如说{ {1}}:

fallbackinf.h

然后在你的.pyx文件中:

#ifndef INFINITY
#define INFINITY 0
#endif

(你不能分配给INFINITY,因为它是一个右值。如果在标题中#defined INFINITY为1.0 / 0.0,你可以取消三元运算符,但这可能会提高SIGFPE,具体取决于你的编译器。)

这绝对是货物崇拜优化的范畴。)

答案 1 :(得分:13)

在Cython中这样做的推荐方法是:

from numpy.math cimport INFINITY

请注意,这是一个“cimport”而不是常规导入。这是Cython围绕NumPy npymath的官方包装。

答案 2 :(得分:4)

您可以使用Numpy的数学库see here for what's available

cdef extern from "numpy/npy_math.h":
    double inf "NPY_INFINITY"

构建Cython扩展模块时,需要指定正确的包含目录和库以进行链接:

>>> from numpy.distutils.misc_util import get_info
>>> get_info('npymath')
{'define_macros': [], 
 'libraries': ['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或您使用的任何构建系统。