pythonoptimizationnumpyscipycython

How to represent inf or -inf in Cython with numpy?


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

Solution

  • 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.)