diff options
-rw-r--r-- | numpy/core/setup.py | 3 | ||||
-rw-r--r-- | numpy/core/src/multiarray/multiarray_tests.c.src | 119 | ||||
-rw-r--r-- | numpy/core/src/private/npy_config.h | 4 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 41 |
4 files changed, 165 insertions, 2 deletions
diff --git a/numpy/core/setup.py b/numpy/core/setup.py index 4c3ec66fe..f56e705ab 100644 --- a/numpy/core/setup.py +++ b/numpy/core/setup.py @@ -934,7 +934,8 @@ def configuration(parent_package='',top_path=None): sources=[join('src', 'multiarray', 'multiarray_tests.c.src'), join('src', 'private', 'mem_overlap.c')], depends=[join('src', 'private', 'mem_overlap.h'), - join('src', 'private', 'npy_extint128.h')]) + join('src', 'private', 'npy_extint128.h')], + libraries=['npymath']) ####################################################################### # operand_flag_tests module # diff --git a/numpy/core/src/multiarray/multiarray_tests.c.src b/numpy/core/src/multiarray/multiarray_tests.c.src index 657c4064e..a20cf6257 100644 --- a/numpy/core/src/multiarray/multiarray_tests.c.src +++ b/numpy/core/src/multiarray/multiarray_tests.c.src @@ -3,6 +3,7 @@ #include <Python.h> #define _NPY_NO_DEPRECATIONS /* for NPY_CHAR */ #include "numpy/arrayobject.h" +#include "numpy/npy_math.h" #include "mem_overlap.h" #include "npy_extint128.h" #include "common.h" @@ -1586,10 +1587,98 @@ get_fpu_mode(PyObject *NPY_UNUSED(self), PyObject *args) return PyLong_FromLongLong(cw); } #else - return Py_RETURN_NONE; + Py_RETURN_NONE; #endif } +/* + * npymath wrappers + */ + +/**begin repeat + * #name = cabs, carg# + */ + +/**begin repeat1 + * #itype = npy_cfloat, npy_cdouble, npy_clongdouble# + * #ITYPE = NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE# + * #otype = npy_float, npy_double, npy_longdouble# + * #OTYPE = NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE# + * #suffix= f, , l# + */ + +static PyObject * +call_npy_@name@@suffix@(PyObject *NPY_UNUSED(self), PyObject *args) +{ + PyObject *z_py = NULL, *z_arr = NULL, *w_arr = NULL; + + if (!PyArg_ParseTuple(args, "O", &z_py)) { + return NULL; + } + + z_arr = PyArray_FROMANY(z_py, @ITYPE@, 0, 0, NPY_ARRAY_CARRAY_RO); + if (z_arr == NULL) { + return NULL; + } + + w_arr = PyArray_SimpleNew(0, NULL, @OTYPE@); + if (w_arr == NULL) { + Py_DECREF(z_arr); + return NULL; + } + + *(@otype@*)PyArray_DATA((PyArrayObject *)w_arr) = + npy_@name@@suffix@(*(@itype@*)PyArray_DATA((PyArrayObject *)z_arr)); + + Py_DECREF(z_arr); + return w_arr; +} + +/**end repeat1**/ + +/**end repeat**/ + +/**begin repeat + * #name = log10, cosh, sinh, tan, tanh# + */ + +/**begin repeat1 + * #type = npy_float, npy_double, npy_longdouble# + * #TYPE = NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE# + * #suffix= f, , l# + */ + +static PyObject * +call_npy_@name@@suffix@(PyObject *NPY_UNUSED(self), PyObject *args) +{ + PyObject *z_py = NULL, *z_arr = NULL, *w_arr = NULL; + + if (!PyArg_ParseTuple(args, "O", &z_py)) { + return NULL; + } + + z_arr = PyArray_FROMANY(z_py, @TYPE@, 0, 0, NPY_ARRAY_CARRAY_RO); + if (z_arr == NULL) { + return NULL; + } + + w_arr = PyArray_SimpleNew(0, NULL, @TYPE@); + if (w_arr == NULL) { + Py_DECREF(z_arr); + return NULL; + } + + *(@type@*)PyArray_DATA((PyArrayObject *)w_arr) = + npy_@name@@suffix@(*(@type@*)PyArray_DATA((PyArrayObject *)z_arr)); + + Py_DECREF(z_arr); + return w_arr; +} + +/**end repeat1**/ + +/**end repeat**/ + static PyMethodDef Multiarray_TestsMethods[] = { {"IsPythonScalar", @@ -1684,6 +1773,34 @@ static PyMethodDef Multiarray_TestsMethods[] = { {"get_fpu_mode", get_fpu_mode, METH_VARARGS, get_fpu_mode_doc}, +/**begin repeat + * #name = cabs, carg# + */ + +/**begin repeat1 + * #suffix = f, , l# + */ + {"npy_@name@@suffix@", + call_npy_@name@@suffix@, + METH_VARARGS, NULL}, +/**end repeat1**/ + +/**end repeat**/ + +/**begin repeat + * #name = log10, cosh, sinh, tan, tanh# + */ + +/**begin repeat1 + * #suffix= f, , l# + */ + {"npy_@name@@suffix@", + call_npy_@name@@suffix@, + METH_VARARGS, NULL}, +/**end repeat1**/ + +/**end repeat**/ + {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/numpy/core/src/private/npy_config.h b/numpy/core/src/private/npy_config.h index 1e2151447..107b3cb5b 100644 --- a/numpy/core/src/private/npy_config.h +++ b/numpy/core/src/private/npy_config.h @@ -65,6 +65,10 @@ /* MSVC _hypot messes with fp precision mode on 32-bit, see gh-9567 */ #if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(_WIN64) +#undef HAVE_CABS +#undef HAVE_CABSF +#undef HAVE_CABSL + #undef HAVE_HYPOT #undef HAVE_HYPOTF #undef HAVE_HYPOTL diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index e7da5d70a..ba4b0e0d8 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -6933,5 +6933,46 @@ def test_equal_override(): assert_equal(array != my_always_equal, 'ne') +def test_npymath_complex(): + # Smoketest npymath functions + from numpy.core.multiarray_tests import ( + npy_cabs, npy_carg) + + funcs = {npy_cabs: np.absolute, + npy_carg: np.angle} + vals = (1, np.inf, -np.inf, np.nan) + types = (np.complex64, np.complex128, np.clongdouble) + + for fun, npfun in funcs.items(): + for x, y in itertools.product(vals, vals): + for t in types: + z = t(complex(x, y)) + got = fun(z) + expected = npfun(z) + assert_allclose(got, expected) + + +def test_npymath_real(): + # Smoketest npymath functions + from numpy.core.multiarray_tests import ( + npy_log10, npy_cosh, npy_sinh, npy_tan, npy_tanh) + + funcs = {npy_log10: np.log10, + npy_cosh: np.cosh, + npy_sinh: np.sinh, + npy_tan: np.tan, + npy_tanh: np.tanh} + vals = (1, np.inf, -np.inf, np.nan) + types = (np.float32, np.float64, np.longdouble) + + with np.errstate(all='ignore'): + for fun, npfun in funcs.items(): + for x, t in itertools.product(vals, types): + z = t(x) + got = fun(z) + expected = npfun(z) + assert_allclose(got, expected) + + if __name__ == "__main__": run_module_suite() |