Skip to content

[BUG] Sort on signed integer #744

@DavyGillebert

Description

@DavyGillebert

Describe the bug
We use an older version of ulab ( 6.7.3-3D-cm, january 2025 ) however I verified and the bug is still in it.

We noticed the bug using np.mean() on arrays of signed integer. I looked into the source code and iets actually the numerical _sort_helper that has the bug, its casts my signed integers to unsigned during the sort. I added the diff I use to fix it

from ulab import numpy as np

a = np.array([[-6 , -8, -26, -5, 6, -3, -19, -5, -20, -6],
              [73 , 0 , -24, 7 , 93, 2, -14, 3, -13, -2],
              [-10, 0 , -10, -2, -15, -8, -16, -6, -17, -2]], dtype=np.int16)

expected_median = np.array([ -6.,   0., -24.,  -2.,   6.,  -3., -16.,  -5., -17.,  -2.])

def validate_median(array, expected):
    calculated = np.median(array, axis=0)
    print("CALC:", calculated)
    print("EXPE:", expected)
    assert np.all(calculated == expected), f"Expected {expected}, but got {calculated}"
    print("Median calculation is correct.")
    
validate_median(a, expected_median)

I fixed it locally right now with:

diff --git a/code/numpy/numerical.c b/code/numpy/numerical.c
index 9a3ee32..da3bbfa 100644
--- a/code/numpy/numerical.c
+++ b/code/numpy/numerical.c
@@ -653,9 +653,13 @@ static mp_obj_t numerical_sort_helper(mp_obj_t oin, mp_obj_t axis, uint8_t inpla
 
     uint8_t *array = (uint8_t *)ndarray->array;
     if(ndarray->shape[ax]) {
-        if((ndarray->dtype == NDARRAY_UINT8) || (ndarray->dtype == NDARRAY_INT8)) {
+        if(ndarray->dtype == NDARRAY_INT8) {
+            HEAPSORT(ndarray, int8_t, array, shape, strides, ax, increment, ndarray->shape[ax]);
+        } else if(ndarray->dtype == NDARRAY_UINT8) {
             HEAPSORT(ndarray, uint8_t, array, shape, strides, ax, increment, ndarray->shape[ax]);
-        } else if((ndarray->dtype == NDARRAY_UINT16) || (ndarray->dtype == NDARRAY_INT16)) {
+        } else if (ndarray->dtype == NDARRAY_INT16) {
+            HEAPSORT(ndarray, int16_t, array, shape, strides, ax, increment, ndarray->shape[ax]);
+        } else if(ndarray->dtype == NDARRAY_UINT16) {
             HEAPSORT(ndarray, uint16_t, array, shape, strides, ax, increment, ndarray->shape[ax]);
         } else {
             HEAPSORT(ndarray, mp_float_t, array, shape, strides, ax, increment, ndarray->shape[ax]);

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions