skdh.utility.math.moving_sd#
- skdh.utility.math.moving_sd(a, w_len, skip, trim=True, axis=-1, return_previous=True)#
Compute the moving sample standard deviation.
- Parameters:
- aarray-like
Signal to compute moving sample standard deviation for.
- w_lenint
Window length in number of samples.
- skipint
Window start location skip in number of samples.
- trimbool, optional
Trim the ends of the result, where a value cannot be calculated. If False, these values will be set to NaN. Default is True.
- axisint, optional
Axis to compute the moving standard deviation along. Default is -1.
- return_previousbool, optional
Return previous moments. These are computed either way, and are therefore optional returns. Default is True.
- Returns:
- msdnumpy.ndarray
Moving sample standard deviation. Note that if the moving axis is not the last axis, then the result will not be c-contiguous.
- mmeannumpy.ndarray, optional.
Moving mean. Note that if the moving axis is not the last axis, then the result will not be c-contiguous. Only returned if return_previous=True.
Warning
Catastropic cancellation is a concern when skip is less than wlen due to the cumulative sum-type algorithms being used, when input values are very very large, or very very small. With typical IMU data values this should not be an issue, even for very long data series (multiple days worth of data).
Notes
On the moving axis, the output length can be computed as follows:
\[\frac{n - w_{len}}{skip} + 1\]where n is the length of the moving axis. For cases where skip != 1 and trim=False, the length of the return on the moving axis can be calculated as:
\[\frac{n}{skip}\]Most efficient computations are for skip values that are either factors of wlen, or greater or equal to wlen.
Examples
Compute the with non-overlapping windows:
>>> import numpy as np >>> x = np.arange(10)**2 >>> moving_sd(x, 3, 3, return_previous=True) (array([ 2.081666 , 8.02080628, 14.0118997 ]), array([ 1.66666667, 16.66666667, 49.66666667]))
Compute with overlapping windows:
>>> moving_mean(x, 3, 1, return_previous=False) array([ 2.081666 , 4.04145188, 6.02771377, 8.02080628, 10.0166528 , 12.01388086, 14.0118997 , 16.01041328])
Compute without trimming:
>>> moving_mean(x, 3, 1, trim=False, return_previous=False) array([ 2.081666 , 4.04145188, 6.02771377, 8.02080628, 10.0166528 , 12.01388086, 14.0118997 , 16.01041328, nan, nan])
Compute on a nd-array to see output shape. On the moving axis, the output should be equal to \((n - w_{len}) / skip + 1\).
>>> n = 500 >>> window_length = 100 >>> window_skip = 50 >>> shape = (3, n, 5, 10) >>> y = np.random.random(shape) >>> res = moving_sd(y, window_length, window_skip, axis=1, return_previous=False) >>> print(res.shape) (3, 9, 5, 10)
Check flags for different axis output
>>> z = np.random.random((10, 10, 10)) >>> moving_sd(z, 3, 3, axis=0, return_previous=False).flags['C_CONTIGUOUS'] False
>>> moving_sd(z, 3, 3, axis=1, return_previous=False).flags['C_CONTIGUOUS'] False
>>> moving_sd(z, 3, 3, axis=2, return_previous=False).flags['C_CONTIGUOUS'] True