Skip to content

[BUG] Test fail with numpy2 for stomp_squared_matrix_profile #2236

@TonyBagnall

Description

@TonyBagnall

Describe the bug

in the module similarity_searc/matrix_profiles the test function test_stomp_squared_matrix_profile fails with numpy 2.0 if this parameter is

K_VALUES = [1,3]

this is caused by the np.argsort method, which by default uses the unstable quicksort which means occasional differences in ties with the two versions.

        id_bests = np.vstack(
            np.unravel_index(
                np.argsort(expected.ravel(), kind="stable"), expected.shape
            )
        ).T

The case K_VALUES = [1] is fixed by making this call stable, but not at all sure about case with 3. See #2216 for more details

Steps/Code to reproduce the bug

No response

Expected results

set K_VALUES = [1,3] and run with numpy <2.0 (passes) and numpy>=2.0 (fails)

Actual results

aeon\similarity_search\matrix_profiles\tests\test_stomp.py:45 (test_stomp_squared_matrix_profile[3-int64])
dtype = 'int64', k = 3

    @pytest.mark.parametrize("dtype", DATATYPES)
    @pytest.mark.parametrize("k", K_VALUES)
    def test_stomp_squared_matrix_profile(dtype, k):
        """Test naive series search."""
        X = np.asarray(
            [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype
        )
    
        S = np.asarray([[3, 4, 5, 4, 3, 4, 5, 3, 2, 4, 5]], dtype=dtype)
        L = 3
        mask = np.ones((X.shape[0], X.shape[2] - L + 1), dtype=bool)
        distance = get_distance_function("squared")
        mp, ip = stomp_squared_matrix_profile(X, S, L, mask, k=k)
        for i in range(S.shape[-1] - L + 1):
            q = S[:, i : i + L]
    
            expected = np.array(
                [
                    [distance(q, X[j, :, _i : _i + L]) for _i in range(X.shape[-1] - L + 1)]
                    for j in range(X.shape[0])
                ]
            )
            id_bests = np.vstack(
                np.unravel_index(
                    np.argsort(expected.ravel(), kind="stable"), expected.shape
                )
            ).T
    
            for j in range(k):
                assert_almost_equal(mp[i][j], expected[id_bests[j, 0], id_bests[j, 1]])
>               assert_equal(ip[i][j], id_bests[j])

L          = 3
S          = array([[3, 4, 5, 4, 3, 4, 5, 3, 2, 4, 5]])
X          = array([[[1, 2, 3, 4, 5, 6, 7, 8]],

       [[1, 2, 4, 4, 5, 6, 5, 4]]])
distance   = CPUDispatcher(<function squared_distance at 0x000002D04F561820>)
dtype      = 'int64'
expected   = array([[20., 11.,  8., 11., 20., 35.],
       [21., 10.,  5., 11.,  8.,  3.]])
i          = 2
id_bests   = array([[1, 5],
       [1, 2],
       [0, 2],
       [1, 4],
       [1, 1],
       [0, 1],
       [0, 3],
       [1, 3],
       [0, 0],
       [0, 4],
       [1, 0],
       [0, 5]])
ip         = array([array([[0, 2],
              [1, 2],
              [1, 1]]), array([[1, 2],
                               [0, 2],
                               [1, 4]]), array([[1, 5],
                                                [1, 2],
                                                [1, 4]]), array([[1, 2],
                                                                 [0, 2],
                                                                 [0, 1]]),
       array([[0, 2],
              [1, 2],
              [1, 1]]), array([[1, 2],
                               [1, 5],
                               [1, 1]]), array([[1, 5],
                                                [1, 2],
                                                [0, 1]]), array([[0, 1],
                                                                 [1, 0],
                                                                 [0, 0]]),
       array([[0, 2],
              [1, 1],
              [0, 1]])], dtype=object)
j          = 2
k          = 3
mask       = array([[ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True]])
mp         = array([array([0., 1., 2.]), array([2., 3., 3.]), array([3., 5., 8.]),
       array([2., 3., 4.]), array([0., 1., 2.]), array([5., 5., 6.]),
       array([ 9., 11., 13.]), array([2., 4., 5.]), array([1., 1., 2.])],
      dtype=object)
q          = array([[5, 4, 3]])

test_stomp.py:76: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\..\..\venv2\lib\site-packages\numpy\_utils\__init__.py:85: in wrapper
    return fun(*args, **kwargs)
        args       = (array([1, 4]), array([0, 2]), '', True)
        dep_version = '2.0.0'
        fun        = <function assert_array_equal at 0x000002D04D36CD30>
        kwargs     = {'strict': False}
        new_name   = 'desired'
        new_names  = ['actual', 'desired']
        old_name   = 'y'
        old_names  = ['x', 'y']
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

args = (<built-in function eq>, array([1, 4]), array([0, 2]))
kwds = {'err_msg': '', 'header': 'Arrays are not equal', 'strict': False, 'verbose': True}

    @wraps(func)
    def inner(*args, **kwds):
        with self._recreate_cm():
>           return func(*args, **kwds)
E           AssertionError: 
E           Arrays are not equal
E           
E           Mismatched elements: 2 / 2 (100%)
E           Max absolute difference among violations: 2
E           Max relative difference among violations: 1.
E            ACTUAL: array([1, 4])
E            DESIRED: array([0, 2])

args       = (<built-in function eq>, array([1, 4]), array([0, 2]))
func       = <function assert_array_compare at 0x000002D04D36CB80>
kwds       = {'err_msg': '',
 'header': 'Arrays are not equal',
 'strict': False,
 'verbose': True}
self       = <contextlib._GeneratorContextManager object at 0x000002D04D374220>

C:\Users\Tony\AppData\Local\Programs\Python\Python39\lib\contextlib.py:79: AssertionError


PASSED [ 73%]PASSED [ 80%]FAILED       [ 86%]
aeon\similarity_search\matrix_profiles\tests\test_stomp.py:45 (test_stomp_squared_matrix_profile[3-float64])
dtype = 'float64', k = 3

    @pytest.mark.parametrize("dtype", DATATYPES)
    @pytest.mark.parametrize("k", K_VALUES)
    def test_stomp_squared_matrix_profile(dtype, k):
        """Test naive series search."""
        X = np.asarray(
            [[[1, 2, 3, 4, 5, 6, 7, 8]], [[1, 2, 4, 4, 5, 6, 5, 4]]], dtype=dtype
        )
    
        S = np.asarray([[3, 4, 5, 4, 3, 4, 5, 3, 2, 4, 5]], dtype=dtype)
        L = 3
        mask = np.ones((X.shape[0], X.shape[2] - L + 1), dtype=bool)
        distance = get_distance_function("squared")
        mp, ip = stomp_squared_matrix_profile(X, S, L, mask, k=k)
        for i in range(S.shape[-1] - L + 1):
            q = S[:, i : i + L]
    
            expected = np.array(
                [
                    [distance(q, X[j, :, _i : _i + L]) for _i in range(X.shape[-1] - L + 1)]
                    for j in range(X.shape[0])
                ]
            )
            id_bests = np.vstack(
                np.unravel_index(
                    np.argsort(expected.ravel(), kind="stable"), expected.shape
                )
            ).T
    
            for j in range(k):
                assert_almost_equal(mp[i][j], expected[id_bests[j, 0], id_bests[j, 1]])
>               assert_equal(ip[i][j], id_bests[j])

L          = 3
S          = array([[3., 4., 5., 4., 3., 4., 5., 3., 2., 4., 5.]])
X          = array([[[1., 2., 3., 4., 5., 6., 7., 8.]],

       [[1., 2., 4., 4., 5., 6., 5., 4.]]])
distance   = CPUDispatcher(<function squared_distance at 0x000002D04F561820>)
dtype      = 'float64'
expected   = array([[20., 11.,  8., 11., 20., 35.],
       [21., 10.,  5., 11.,  8.,  3.]])
i          = 2
id_bests   = array([[1, 5],
       [1, 2],
       [0, 2],
       [1, 4],
       [1, 1],
       [0, 1],
       [0, 3],
       [1, 3],
       [0, 0],
       [0, 4],
       [1, 0],
       [0, 5]])
ip         = array([array([[0, 2],
              [1, 2],
              [1, 1]]), array([[1, 2],
                               [0, 2],
                               [1, 4]]), array([[1, 5],
                                                [1, 2],
                                                [1, 4]]), array([[1, 2],
                                                                 [0, 2],
                                                                 [0, 1]]),
       array([[0, 2],
              [1, 2],
              [1, 1]]), array([[1, 2],
                               [1, 5],
                               [1, 1]]), array([[1, 5],
                                                [1, 2],
                                                [0, 1]]), array([[0, 1],
                                                                 [1, 0],
                                                                 [0, 0]]),
       array([[0, 2],
              [1, 1],
              [0, 1]])], dtype=object)
j          = 2
k          = 3
mask       = array([[ True,  True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True,  True]])
mp         = array([array([0., 1., 2.]), array([2., 3., 3.]), array([3., 5., 8.]),
       array([2., 3., 4.]), array([0., 1., 2.]), array([5., 5., 6.]),
       array([ 9., 11., 13.]), array([2., 4., 5.]), array([1., 1., 2.])],
      dtype=object)
q          = array([[5., 4., 3.]])

test_stomp.py:76: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
..\..\..\..\venv2\lib\site-packages\numpy\_utils\__init__.py:85: in wrapper
    return fun(*args, **kwargs)
        args       = (array([1, 4]), array([0, 2]), '', True)
        dep_version = '2.0.0'
        fun        = <function assert_array_equal at 0x000002D04D36CD30>
        kwargs     = {'strict': False}
        new_name   = 'desired'
        new_names  = ['actual', 'desired']
        old_name   = 'y'
        old_names  = ['x', 'y']
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

args = (<built-in function eq>, array([1, 4]), array([0, 2]))
kwds = {'err_msg': '', 'header': 'Arrays are not equal', 'strict': False, 'verbose': True}

    @wraps(func)
    def inner(*args, **kwds):
        with self._recreate_cm():
>           return func(*args, **kwds)
E           AssertionError: 
E           Arrays are not equal
E           
E           Mismatched elements: 2 / 2 (100%)
E           Max absolute difference among violations: 2
E           Max relative difference among violations: 1.
E            ACTUAL: array([1, 4])
E            DESIRED: array([0, 2])

args       = (<built-in function eq>, array([1, 4]), array([0, 2]))
func       = <function assert_array_compare at 0x000002D04D36CB80>
kwds       = {'err_msg': '',
 'header': 'Arrays are not equal',
 'strict': False,
 'verbose': True}
self       = <contextlib._GeneratorContextManager object at 0x000002D04D374220>

C:\Users\Tony\AppData\Local\Programs\Python\Python39\lib\contextlib.py:79: AssertionError

Versions

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingsimilarity searchSimilarity search packagetestingTesting related issue or pull request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions