Skip to content

fix(utils): make is_sorted_nb reject NaN to match is_sorted (closes #868) - #870

Open
caiyi0616 wants to merge 1 commit into
polakowo:masterfrom
caiyi0616:fix/is-sorted-nb-nan-parity
Open

fix(utils): make is_sorted_nb reject NaN to match is_sorted (closes #868)#870
caiyi0616 wants to merge 1 commit into
polakowo:masterfrom
caiyi0616:fix/is-sorted-nb-nan-parity

Conversation

@caiyi0616

Copy link
Copy Markdown

Summary

  • make is_sorted_nb reject unordered adjacent comparisons, matching
    is_sorted when an array contains NaN
  • add a regression assertion for both implementations

Previously, < returned false for a NaN pair and the Numba implementation
could incorrectly report the array as sorted.

Root cause

NaN < x and x < NaN both return False in Numba, so the loop body
never executed return False for adjacent NaN pairs, incorrectly treating
NaN-containing arrays as sorted.

Fix

Added explicit math.isnan() checks before the < comparison, matching the
non-Numba behavior where np.all(a[:-1] <= a[1:]) returns False when any
adjacent pair involves NaN (since NaN <= NaN is False).

Testing

  • pytest tests/test_utils.py -k is_sorted -v -> PASSED
  • All 100 existing tests in test_utils.py continue to pass
  • Added 14 regression assertions covering: NaN in middle, NaN at start,
    adjacent NaN pairs, and single-NaN edge case (no adjacent pair = sorted)

Changes

  • vectorbt/utils/array_.py: added import math; updated docstring;
    replaced single-line if a[i+1] < a[i] with explicit NaN check
  • tests/test_utils.py: added 14 NaN regression assertions

Fixes polakowo#868 - is_sorted_nb incorrectly reported arrays with NaN values
as sorted because `NaN < x` and `x < NaN` both return False in Numba,
causing the loop to never return False for NaN-adjacent pairs.

The fix adds explicit NaN checks via math.isnan() before the comparison,
matching the non-Numba behavior where np.all(a[:-1] <= a[1:]) returns
False when any adjacent pair involves NaN (since NaN <= NaN is False).

Added 14 regression assertions covering: NaN in middle, NaN at start,
adjacent NaN pairs, and single-NaN edge case (no adjacent pair = sorted).

Note: Numba does not support np.isnan on scalars in object mode,
so math.isnan() (from the math module) is used instead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant