summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/lib/src/_compiled_base.c37
-rw-r--r--numpy/lib/tests/test_function_base.py16
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):