问题
I am building an array with cython element by element. I'd like to store the constant np.inf
(or -1 * np.inf
) in some entries. However, this will require the overhead of going back into Python to look up inf
. Is there a libc.math
equivalent of this constant? Or some other value that could easily be used that's equivalent to (-1*np.inf)
and can be used from Cython without overhead?
EDIT example, you have:
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
回答1:
There's no literal for it, but float
can parse it from a string:
>>> float('inf')
inf
>>> np.inf == float('inf')
True
Alternatively, math.h
may (almost certainly will) declare a macro that evaluates to inf, in which case you can just use that:
cdef extern from "math.h":
float INFINITY
(There's no clean way to check if INFINITY is defined in pure Cython, so if you want to cover all your bases you'll need to get hacky. One way of doing it is to create a small C header, say fallbackinf.h
:
#ifndef INFINITY
#define INFINITY 0
#endif
And then in your .pyx file:
cdef extern from "math.h":
float INFINITY
cdef extern from "fallbackinf.h":
pass
inf = INFINITY if INFINITY != 0 else float('inf')
(You can't assign to INFINITY, because it's an rvalue. You could do away with the ternary operator if you #defined INFINITY as 1.0/0.0 in your header, but that might raise SIGFPE, depending on your compiler.)
This is definitely in the realm of cargo cult optimisation, though.)
回答2:
The recommended way of doing this in Cython is:
from numpy.math cimport INFINITY
Note, that this is a "cimport" rather than a regular import. This is Cython's official wrapper around NumPy's npymath
.
回答3:
You can use Numpy's math library, see here for what's available:
cdef extern from "numpy/npy_math.h": double inf "NPY_INFINITY"
When building the Cython extension module, you need to specify the correct include directory and library to link:
>>> 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']}
The information obtained from that function can be passed onto Python distutils, or whatever build system you use.
来源:https://stackoverflow.com/questions/16050549/how-to-represent-inf-or-inf-in-cython-with-numpy