diff options
author | Marten van Kerkwijk <mhvk@astro.utoronto.ca> | 2018-06-07 14:35:21 -0400 |
---|---|---|
committer | Marten van Kerkwijk <mhvk@astro.utoronto.ca> | 2018-06-07 14:37:21 -0400 |
commit | b02fa32630d9879453a9a35579b31a17fe6e3307 (patch) | |
tree | d8767b442c857d63ba016ad13884725ed0b10708 /numpy | |
parent | c5ef41148a7d65f68a7471eac5993a0572089a48 (diff) | |
download | numpy-b02fa32630d9879453a9a35579b31a17fe6e3307.tar.gz |
TST: Add a new gufunc with (i)->(i) signature for testing with axis.
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/umath/_umath_tests.c.src | 46 | ||||
-rw-r--r-- | numpy/core/tests/test_ufunc.py | 19 |
2 files changed, 64 insertions, 1 deletions
diff --git a/numpy/core/src/umath/_umath_tests.c.src b/numpy/core/src/umath/_umath_tests.c.src index 2a74c1aaa..fcbdbe330 100644 --- a/numpy/core/src/umath/_umath_tests.c.src +++ b/numpy/core/src/umath/_umath_tests.c.src @@ -253,6 +253,38 @@ static void /**end repeat**/ +char *cumsum_signature = "(i)->(i)"; + +/* + * This implements the function + * out[n] = sum_i^n in[i] + */ + +/**begin repeat + + #TYPE=LONG,DOUBLE# + #typ=npy_long,npy_double# +*/ + +static void +@TYPE@_cumsum(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func)) +{ + INIT_OUTER_LOOP_2 + npy_intp di = dimensions[0]; + npy_intp i; + npy_intp is=steps[0], os=steps[1]; + BEGIN_OUTER_LOOP_2 + char *ip=args[0], *op=args[1]; + @typ@ cumsum = 0; + for (i = 0; i < di; i++, ip += is, op += os) { + cumsum += (*(@typ@ *)ip); + *(@typ@ *)op = cumsum; + } + END_OUTER_LOOP +} + +/**end repeat**/ + static PyUFuncGenericFunction inner1d_functions[] = { LONG_inner1d, DOUBLE_inner1d }; static void * inner1d_data[] = { (void *)NULL, (void *)NULL }; @@ -270,6 +302,10 @@ static void *eucldiean_pdist_data[] = { (void *)NULL, (void *)NULL }; static char euclidean_pdist_signatures[] = { NPY_FLOAT, NPY_FLOAT, NPY_DOUBLE, NPY_DOUBLE }; +static PyUFuncGenericFunction cumsum_functions[] = { LONG_cumsum, DOUBLE_cumsum }; +static void * cumsum_data[] = { (void *)NULL, (void *)NULL }; +static char cumsum_signatures[] = { NPY_LONG, NPY_LONG, NPY_DOUBLE, NPY_DOUBLE }; + static int addUfuncs(PyObject *dictionary) { @@ -321,6 +357,16 @@ addUfuncs(PyObject *dictionary) { } PyDict_SetItemString(dictionary, "euclidean_pdist", f); Py_DECREF(f); + f = PyUFunc_FromFuncAndDataAndSignature(cumsum_functions, + cumsum_data, cumsum_signatures, + 2, 1, 1, PyUFunc_None, "cumsum", + "Cumulative sum of the input (n)->(n)\n", + 0, cumsum_signature); + if (f == NULL) { + return -1; + } + PyDict_SetItemString(dictionary, "cumsum", f); + Py_DECREF(f); f = PyUFunc_FromFuncAndDataAndSignature(inner1d_functions, inner1d_data, inner1d_signatures, 2, 2, 1, PyUFunc_None, "inner1d_no_doc", NULL, diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index 80237756d..ef9ced354 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -741,12 +741,21 @@ class TestUfunc(object): assert_array_equal(d, c) c = inner1d(a, b, axis=0) assert_array_equal(c, (a * b).sum(0)) - # Sanity check on innerwt. + # Sanity checks on innerwt and cumsum. a = np.arange(6).reshape((2, 3)) b = np.arange(10, 16).reshape((2, 3)) w = np.arange(20, 26).reshape((2, 3)) assert_array_equal(umt.innerwt(a, b, w, axis=0), np.sum(a * b * w, axis=0)) + assert_array_equal(umt.cumsum(a, axis=0), np.cumsum(a, axis=0)) + assert_array_equal(umt.cumsum(a, axis=-1), np.cumsum(a, axis=-1)) + out = np.empty_like(a) + b = umt.cumsum(a, out=out, axis=0) + assert_(out is b) + assert_array_equal(b, np.cumsum(a, axis=0)) + b = umt.cumsum(a, out=out, axis=1) + assert_(out is b) + assert_array_equal(b, np.cumsum(a, axis=-1)) # Check errors. # Cannot pass in both axis and axes. assert_raises(TypeError, inner1d, a, b, axis=0, axes=[0, 0]) @@ -755,6 +764,9 @@ class TestUfunc(object): # more than 1 core dimensions. mm = umt.matrix_multiply assert_raises(TypeError, mm, a, b, axis=1) + # Output wrong size in axis. + out = np.empty((1, 2, 3), dtype=a.dtype) + assert_raises(ValueError, umt.cumsum, a, out=out, axis=0) # Regular ufuncs should not accept axis. assert_raises(TypeError, np.add, 1., 1., axis=0) @@ -928,6 +940,11 @@ class TestUfunc(object): # An output array is required to determine p with signature (n,d)->(p) assert_raises(ValueError, umt.euclidean_pdist, a) + def test_cumsum(self): + a = np.arange(10) + result = umt.cumsum(a) + assert_array_equal(result, a.cumsum()) + def test_object_logical(self): a = np.array([3, None, True, False, "test", ""], dtype=object) assert_equal(np.logical_or(a, None), |