Skip to content

Commit

Permalink
BUG: wrong selection for orders falling into equal ranges
Browse files Browse the repository at this point in the history
when orders are selected where the kth element falls into an equal range
the the last stored pivot was not the kth element, this leads to losing
the ordering of smaller orders as following selection steps can start at
index 0 again instead of the at the offset of the last selection.
Closes numpygh-4836
  • Loading branch information
juliantaylor committed Aug 4, 2014
1 parent e715bce commit 763aeea
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
10 changes: 7 additions & 3 deletions numpy/core/src/npysort/selection.c.src
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,10 @@ int
/* move pivot into position */
SWAP(SORTEE(low), SORTEE(hh));

store_pivot(hh, kth, pivots, npiv);
/* kth pivot stored later */
if (hh != kth) {
store_pivot(hh, kth, pivots, npiv);
}

if (hh >= kth)
high = hh - 1;
Expand All @@ -389,10 +392,11 @@ int

/* two elements */
if (high == low + 1) {
if (@TYPE@_LT(v[IDX(high)], v[IDX(low)]))
if (@TYPE@_LT(v[IDX(high)], v[IDX(low)])) {
SWAP(SORTEE(high), SORTEE(low))
store_pivot(low, kth, pivots, npiv);
}
}
store_pivot(kth, kth, pivots, npiv);

return 0;
}
Expand Down
18 changes: 18 additions & 0 deletions numpy/core/tests/test_multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,12 @@ def test_partition(self):
d[i:].partition(0, kind=k)
assert_array_equal(d, tgt)

d = np.array([0, 1, 2, 3, 4, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 9])
kth = [0, 3, 19, 20]
assert_equal(np.partition(d, kth, kind=k)[kth], (0, 3, 7, 7))
assert_equal(d[np.argpartition(d, kth, kind=k)][kth], (0, 3, 7, 7))

d = np.array([2, 1])
d.partition(0, kind=k)
assert_raises(ValueError, d.partition, 2)
Expand Down Expand Up @@ -1332,6 +1338,18 @@ def test_partition_cdtype(self):
assert_equal(np.partition(d, k)[k], tgt[k])
assert_equal(d[np.argpartition(d, k)][k], tgt[k])

def test_partition_fuzz(self):
# a few rounds of random data testing
for j in range(10, 30):
for i in range(1, j - 2):
d = np.arange(j)
np.random.shuffle(d)
d = d % np.random.randint(2, 30)
idx = np.random.randint(d.size)
kth = [0, idx, i, i + 1]
tgt = np.sort(d)[kth]
assert_array_equal(np.partition(d, kth)[kth], tgt,
err_msg="data: %r\n kth: %r" % (d, kth))

def test_flatten(self):
x0 = np.array([[1, 2, 3], [4, 5, 6]], np.int32)
Expand Down

0 comments on commit 763aeea

Please sign in to comment.