--- /dev/null
+# NumPy math library
+#
+# This exports the functionality of the NumPy core math library, aka npymath,
+# which provides implementations of C99 math functions and macros for system
+# with a C89 library (such as MSVC). npymath is available with NumPy >=1.3,
+# although some functions will require later versions. The spacing function is
+# not in C99, but comes from Fortran.
+#
+# On the Cython side, the npymath functions are available without the "npy_"
+# prefix that they have in C, to make this is a drop-in replacement for
+# libc.math. The same is true for the constants, where possible.
+#
+# See the NumPy documentation for linking instructions.
+#
+# Complex number support and NumPy 2.0 half-precision functions are currently
+# not exported.
+#
+# Author: Lars Buitinck
+
+cdef extern from "numpy/npy_math.h":
+ # Floating-point classification
+ long double NAN "NPY_NAN"
+ long double INFINITY "NPY_INFINITY"
+ long double PZERO "NPY_PZERO" # positive zero
+ long double NZERO "NPY_NZERO" # negative zero
+
+ # These four are actually macros and work on any floating-point type.
+ bint isfinite "npy_isfinite"(long double)
+ bint isinf "npy_isinf"(long double)
+ bint isnan "npy_isnan"(long double)
+ bint signbit "npy_signbit"(long double)
+
+ double copysign "npy_copysign"(double, double)
+
+ # Math constants
+ long double E "NPY_E"
+ long double LOG2E "NPY_LOG2E" # ln(e) / ln(2)
+ long double LOG10E "NPY_LOG10E" # ln(e) / ln(10)
+ long double LOGE2 "NPY_LOGE2" # ln(2)
+ long double LOGE10 "NPY_LOGE10" # ln(10)
+ long double PI "NPY_PI"
+ long double PI_2 "NPY_PI_2" # pi / 2
+ long double PI_4 "NPY_PI_4" # pi / 4
+ long double NPY_1_PI # 1 / pi; NPY_ because of ident syntax
+ long double NPY_2_PI # 2 / pi
+ long double EULER "NPY_EULER" # Euler constant (gamma, 0.57721)
+
+ # Low-level floating point manipulation (NumPy >=1.4)
+ double nextafter "npy_nextafter"(double x, double y)
+ double spacing "npy_spacing"(double x)
def update_numpy_extension(ext):
import numpy
+ from numpy.distutils.misc_util import get_info
+
ext.include_dirs.append(numpy.get_include())
+ # We need the npymath library for numpy.math.
+ # This is typically a static-only library.
+ for attr, value in get_info('npymath').items():
+ getattr(ext, attr).extend(value)
+
def update_openmp_extension(ext):
ext.openmp = True
language = ext.language
--- /dev/null
+# tag: numpy
+
+cimport numpy.math as npmath
+
+
+def test_fp_classif():
+ """
+ >>> test_fp_classif()
+ """
+
+ cdef double d_zero
+ cdef float f_zero
+
+ d_zero = -1 * 0.
+ f_zero = -1 * 0.
+
+ assert d_zero == npmath.NZERO
+ assert f_zero == npmath.NZERO
+
+ assert npmath.signbit(d_zero)
+ assert npmath.signbit(f_zero)
+
+ d_zero = 1 * 0.
+ f_zero = 1 * 0.
+
+ assert d_zero == npmath.PZERO
+ assert f_zero == npmath.PZERO
+
+ assert not npmath.signbit(d_zero)
+ assert not npmath.signbit(f_zero)
+
+ assert not npmath.isinf(d_zero)
+ assert not npmath.isinf(f_zero)
+
+ assert not npmath.isnan(d_zero)
+ assert not npmath.isnan(f_zero)
+
+ assert npmath.isinf(npmath.INFINITY)
+ assert npmath.isnan(npmath.NAN)
+
+ assert npmath.signbit(npmath.copysign(1., -1.))
+
+
+def test_nextafter():
+ """
+ >>> test_nextafter()
+ """
+
+ x = npmath.nextafter(npmath.EULER, 1)
+ assert npmath.isfinite(x)
+ assert x > npmath.EULER
+
+ x = npmath.nextafter(npmath.PI_4, -1)
+ assert npmath.isfinite(x)
+ assert x < npmath.PI_4