# Author: John Kirkham, Meekail Zain, Thomas Fan | |
from libc.math cimport isnan, isinf | |
from cython cimport floating | |
cpdef enum FiniteStatus: | |
all_finite = 0 | |
has_nan = 1 | |
has_infinite = 2 | |
def cy_isfinite(floating[::1] a, bint allow_nan=False): | |
cdef FiniteStatus result | |
with nogil: | |
result = _isfinite(a, allow_nan) | |
return result | |
cdef inline FiniteStatus _isfinite(floating[::1] a, bint allow_nan) noexcept nogil: | |
cdef floating* a_ptr = &a[0] | |
cdef Py_ssize_t length = len(a) | |
if allow_nan: | |
return _isfinite_allow_nan(a_ptr, length) | |
else: | |
return _isfinite_disable_nan(a_ptr, length) | |
cdef inline FiniteStatus _isfinite_allow_nan(floating* a_ptr, | |
Py_ssize_t length) noexcept nogil: | |
cdef Py_ssize_t i | |
cdef floating v | |
for i in range(length): | |
v = a_ptr[i] | |
if isinf(v): | |
return FiniteStatus.has_infinite | |
return FiniteStatus.all_finite | |
cdef inline FiniteStatus _isfinite_disable_nan(floating* a_ptr, | |
Py_ssize_t length) noexcept nogil: | |
cdef Py_ssize_t i | |
cdef floating v | |
for i in range(length): | |
v = a_ptr[i] | |
if isnan(v): | |
return FiniteStatus.has_nan | |
elif isinf(v): | |
return FiniteStatus.has_infinite | |
return FiniteStatus.all_finite | |