Skip to content

Commit 3b3b565

Browse files
committed
Added test coverage assessment. 100% test coverage
1 parent 23abb5b commit 3b3b565

7 files changed

Lines changed: 28 additions & 67 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
.pytest_cache
77
LOG*
88
PID
9+
.coverage

matrix_profile/core.py

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
import scipy.signal
88
import time
99

10-
def check_python_version():
10+
def check_python_version(): # pragma: no cover
1111
if (sys.version_info < (3, 0)):
1212
raise Exception('Matrix Profile is only compatible with python3.x')
1313

14-
def get_parser():
14+
def get_parser(): # pragma: no cover
1515
parser = argparse.ArgumentParser()
1616
parser.add_argument('ts_file', help='Time series input file')
1717
parser.add_argument('subseq_length', help='Subsequence length', type=int)
@@ -26,15 +26,15 @@ def rolling_window(a, window):
2626
def z_norm(x, axis=0):
2727
return (x - np.mean(x, axis, keepdims=True))/np.std(x, axis, keepdims=True)
2828

29-
def check_dtype(arr, dtype=np.float):
29+
def check_dtype(arr, dtype=np.float): # pragma: no cover
3030
"""
3131
Check if array has correct dtype
3232
"""
3333
if not issubclass(arr.dtype.type, dtype):
3434
msg = '{} type expected but found {}'.format(dtype, arr.dtype.type)
3535
raise TypeError(msg)
3636

37-
def are_arrays_equal(arr1, arr2):
37+
def are_arrays_equal(arr1, arr2): # pragma: no cover
3838
"""
3939
Check if two arrays are equal; first by comparing memory addresses,
4040
and secondly by their values
@@ -45,7 +45,7 @@ def are_arrays_equal(arr1, arr2):
4545

4646
return np.array_equal(arr1, arr2)
4747

48-
def are_distances_too_small(x, threshold=10e-6):
48+
def are_distances_too_small(x, threshold=10e-6): # pragma: no cover
4949
"""
5050
Check the distance values from a matrix profile.
5151
@@ -58,7 +58,7 @@ def are_distances_too_small(x, threshold=10e-6):
5858

5959
return False
6060

61-
def timeit(func):
61+
def timeit(func): # pragma: no cover
6262
"""
6363
Timing decorator
6464
"""
@@ -196,14 +196,3 @@ def mass(Q, T, M_T=None, Σ_T=None):
196196
return calculate_distance_profile(m, QT, μ_Q, σ_Q, M_T, Σ_T)
197197

198198
convolution = scipy.signal.fftconvolve # Swap for other convolution function
199-
200-
if __name__ == '__main__':
201-
check_python_version()
202-
#parser = get_parser()
203-
#args = parser.parse_args()
204-
N = 17279800 # GPU-STOMP Comparison
205-
# Select 50 random floats in range [-1000, 1000]
206-
T = np.random.uniform(-1000, 1000, [N])
207-
# Select 5 random floats in range [-1000, 1000]
208-
Q = np.random.uniform(-1000, 1000, [2000])
209-
mass(Q, T)

matrix_profile/stamp.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,3 @@ def stamp(T_A, T_B, m, ignore_trivial=False):
4949
out = np.array(out, dtype=object)
5050

5151
return out
52-
53-
54-
if __name__ == '__main__':
55-
core.check_python_version()
56-
#parser = get_parser()
57-
#args = parser.parse_args()
58-
#N = 17279800 # GPU-STOMP Comparison
59-
N = 12*24*365 # Every 5 minutes: 12 times an hour, 24 hours, 365 days
60-
M = 12*24
61-
# Select 50 random floats in range [-1000, 1000]
62-
T = np.random.uniform(-1000, 1000, [N])
63-
# Select 5 random floats in range [-1000, 1000]
64-
Q = np.random.uniform(-1000, 1000, [M])

matrix_profile/stomp.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
logger = logging.getLogger(__name__)
99

10-
def _stomp(T_A, T_B, m, ignore_trivial=False):
10+
def _stomp(T_A, T_B, m, ignore_trivial=False): # pragma: no cover
1111
"""
1212
DO NOT USE! Here for reference only.
1313
@@ -95,7 +95,7 @@ def stomp(T_A, T_B, m, ignore_trivial=False):
9595
core.check_dtype(T_A)
9696
core.check_dtype(T_B)
9797

98-
if ignore_trivial == False and core.are_arrays_equal(T_A, T_B):
98+
if ignore_trivial == False and core.are_arrays_equal(T_A, T_B): # pragma: no cover
9999
logger.warn("Arrays T_A, T_B are equal, which implies a self-join.")
100100
logger.warn("Try setting `ignore_trivial = True`.")
101101

@@ -150,23 +150,8 @@ def stomp(T_A, T_B, m, ignore_trivial=False):
150150
out[i] = P, I, IL, IR
151151

152152
threshold = 10e-6
153-
if core.are_distances_too_small(out[:, 0], threshold=threshold):
153+
if core.are_distances_too_small(out[:, 0], threshold=threshold): # pragma: no cover
154154
logger.warn(f"A large number of values are smaller than {threshold}.")
155155
logger.warn("For a self-join, try setting `ignore_trivial = True`.")
156156

157157
return out
158-
159-
if __name__ == '__main__':
160-
core.check_python_version()
161-
#parser = get_parser()
162-
#args = parser.parse_args()
163-
#N = 17279800 # GPU-STOMP Comparison
164-
#N = 12*24*365 # Every 5 minutes: 12 times an hour, 24 hours, 365 days
165-
#M = 12*24
166-
N = 1000
167-
M = 100
168-
# Select 50 random floats in range [-1000, 1000]
169-
T = np.random.uniform(-1000, 1000, [N])
170-
# Select 5 random floats in range [-1000, 1000]
171-
Q = np.random.uniform(-1000, 1000, [M])
172-
stomp(Q, T, 10)

matrix_profile/stump.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def _calculate_squared_distance_profile(m, QT, μ_Q, σ_Q, M_T, Σ_T):
2121

2222
return D_squared
2323

24-
@njit(parallel=True, fastmath=True)
24+
@njit(parallel=True, fastmath=True)
2525
def _stump(T_A, T_B, m, profile, indices, l, zone,
2626
M_T, Σ_T, QT, QT_first, μ_Q, σ_Q, k, ignore_trivial=False):
2727
"""
@@ -111,7 +111,7 @@ def stump(T_A, T_B, m, ignore_trivial=False):
111111
core.check_dtype(T_A)
112112
core.check_dtype(T_B)
113113

114-
if ignore_trivial == False and core.are_arrays_equal(T_A, T_B):
114+
if ignore_trivial == False and core.are_arrays_equal(T_A, T_B): # pragma: no cover
115115
logger.warn("Arrays T_A, T_B are equal, which implies a self-join.")
116116
logger.warn("Try setting `ignore_trivial = True`.")
117117

@@ -148,23 +148,8 @@ def stump(T_A, T_B, m, ignore_trivial=False):
148148
out[:, 1:4] = indices
149149

150150
threshold = 10e-6
151-
if core.are_distances_too_small(out[:, 0], threshold=threshold):
151+
if core.are_distances_too_small(out[:, 0], threshold=threshold): # pragma: no cover
152152
logger.warn(f"A large number of values are smaller than {threshold}.")
153153
logger.warn("For a self-join, try setting `ignore_trivial = True`.")
154154

155155
return out
156-
157-
if __name__ == '__main__':
158-
core.check_python_version()
159-
#parser = get_parser()
160-
#args = parser.parse_args()
161-
#N = 17279800 # GPU-STOMP Comparison
162-
#N = 12*24*365 # Every 5 minutes: 12 times an hour, 24 hours, 365 days
163-
#M = 12*24
164-
N = 1000
165-
M = 100
166-
# Select 50 random floats in range [-1000, 1000]
167-
T = np.random.uniform(-1000, 1000, [N])
168-
# Select 5 random floats in range [-1000, 1000]
169-
Q = np.random.uniform(-1000, 1000, [M])
170-
stump(Q, T, 10)

test.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
#!/bin/sh
22

3-
python3 `which pytest` --capture=sys -s
3+
export NUMBA_DISABLE_JIT=1
4+
SITE_PACKAGES_DIR=`pip show matrix_profile | grep Location | awk '{print $2}'`
5+
py.test --cov=$SITE_PACKAGES_DIR/matrix_profile --cov-report term-missing tests/ --capture=sys -s

tests/test_stump.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import numpy as np
33
import numpy.testing as npt
44
from matrix_profile import stump, core
5+
import numba as nb
56
import pytest
67

78
def naive_mass(Q, T, m, trivial_idx=None, excl_zone=0, ignore_trivial=False):
@@ -46,6 +47,17 @@ def replace_inf(x, value=0):
4647
(np.random.uniform(-1000, 1000, [8]).astype(np.float64), np.random.uniform(-1000, 1000, [64]).astype(np.float64))
4748
]
4849

50+
@pytest.mark.parametrize("Q, T", test_data)
51+
def test_calculate_squared_distance_profile(Q, T):
52+
m = Q.shape[0]
53+
left = np.linalg.norm(core.z_norm(core.rolling_window(T, m), 1) - core.z_norm(Q), axis=1)
54+
left = np.square(left[0])
55+
M_T, Σ_T = core.compute_mean_std(Q, m)
56+
QT = core.sliding_dot_product(T[:m], Q)
57+
μ_Q, σ_Q = core.compute_mean_std(T, m)
58+
right = stump._calculate_squared_distance_profile(m, QT, μ_Q[0], σ_Q[0], M_T, Σ_T)
59+
npt.assert_almost_equal(left, right)
60+
4961
@pytest.mark.parametrize("T_A, T_B", test_data)
5062
def test_stump_self_join(T_A, T_B):
5163
m = 3

0 commit comments

Comments
 (0)