diff options
-rw-r--r-- | numpy/lib/src/_compiled_base.c | 37 | ||||
-rw-r--r-- | numpy/lib/tests/test_function_base.py | 16 |
2 files changed, 41 insertions, 12 deletions
diff --git a/numpy/lib/src/_compiled_base.c b/numpy/lib/src/_compiled_base.c index 328fc2d14..c91855e81 100644 --- a/numpy/lib/src/_compiled_base.c +++ b/numpy/lib/src/_compiled_base.c @@ -60,29 +60,44 @@ decr_slot_right_(double x, double * bins, npy_intp lbins) return 0; } -/** +/* * Returns -1 if the array is monotonic decreasing, * +1 if the array is monotonic increasing, * and 0 if the array is not monotonic. */ static int -check_array_monotonic(double * a, int lena) +check_array_monotonic(const double *a, npy_int lena) { - int i; + npy_intp i; + double next; + double last = a[0]; - if (a [0] <= a [1]) { - /* possibly monotonic increasing */ - for (i = 1; i < lena - 1; i ++) { - if (a [i] > a [i + 1]) { + /* Skip repeated values at the beginning of the array */ + for (i = 1; (i < lena) && (a[i] == last); i++); + + if (i == lena) { + /* all bin edges hold the same value */ + return 1; + } + + next = a[i]; + if (last < next) { + /* Possibly monotonic increasing */ + for (i += 1; i < lena; i++) { + last = next; + next = a[i]; + if (last > next) { return 0; } } return 1; } else { - /* possibly monotonic decreasing */ - for (i = 1; i < lena - 1; i ++) { - if (a [i] < a [i + 1]) { + /* last > next, possibly monotonic decreasing */ + for (i += 1; i < lena; i++) { + last = next; + next = a[i]; + if (last < next) { return 0; } } @@ -90,8 +105,6 @@ check_array_monotonic(double * a, int lena) } } - - /* find the index of the maximum element of an integer array */ static npy_intp mxx (npy_intp *i , npy_intp len) diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py index 4d2360b69..003d3e541 100644 --- a/numpy/lib/tests/test_function_base.py +++ b/numpy/lib/tests/test_function_base.py @@ -761,6 +761,22 @@ class TestDigitize(TestCase): bins = np.linspace(x.min(), x.max(), 10) assert_(np.all(digitize(x, bins, True) != 10)) + def test_monotonic(self): + x = [-1, 0, 1, 2] + bins = [0, 0, 1] + assert_array_equal(digitize(x, bins, False), [0, 2, 3, 3]) + assert_array_equal(digitize(x, bins, True), [0, 0, 2, 3]) + bins = [1, 1, 0] + assert_array_equal(digitize(x, bins, False), [3, 2, 0, 0]) + assert_array_equal(digitize(x, bins, True), [3, 3, 2, 0]) + bins = [1, 1, 1, 1] + assert_array_equal(digitize(x, bins, False), [0, 0, 4, 4]) + assert_array_equal(digitize(x, bins, True), [0, 0, 0, 4]) + bins = [0, 0, 1, 0] + assert_raises(ValueError, digitize, x, bins) + bins = [1, 1, 0, 1] + assert_raises(ValueError, digitize, x, bins) + class TestUnwrap(TestCase): def test_simple(self): |