Source code for neurokit2.complexity.utils_complexity_ordinalpatterns

import numpy as np

from .utils_complexity_embedding import complexity_embedding


[docs] def complexity_ordinalpatterns(signal, delay=1, dimension=3, algorithm="quicksort", **kwargs): """**Find Ordinal Patterns for Permutation Procedures** The seminal work by Bandt and Pompe (2002) introduced a symbolization approach to obtain a sequence of ordinal patterns (permutations) from continuous data. It is used in :func:`permutation entropy <entropy_permutation>` and its different variants. Parameters ---------- signal : Union[list, np.array, pd.Series] The signal (i.e., a time series) in the form of a vector of values. delay : int Time delay (often denoted *Tau* :math:`\\tau`, sometimes referred to as *lag*) in samples. See :func:`complexity_delay` to estimate the optimal value for this parameter. dimension : int Embedding Dimension (*m*, sometimes referred to as *d* or *order*). See :func:`complexity_dimension` to estimate the optimal value for this parameter. algorithm : str Can be ``"quicksort"`` (default) or ``"bubblesort"`` (used in Bubble Entropy). Returns ------- array Ordinal patterns. vector Frequencies of each ordinal pattern. dict A dictionary containing additional elements. Examples ---------- Example given by Bandt and Pompe (2002): .. ipython:: python import neurokit2 as nk signal = [4, 7, 9, 10, 6, 11, 3] patterns, info = nk.complexity_ordinalpatterns(signal, delay=1, dimension=3) patterns info["Frequencies"] .. ipython:: python signal = [4, 7, 9, 10, 6, 5, 3, 6, 8, 9, 5, 1, 0] patterns, info = nk.complexity_ordinalpatterns(signal, algorithm="bubblesort") info["Frequencies"] References ---------- * Bandt, C., & Pompe, B. (2002). Permutation entropy: a natural complexity measure for time series. Physical review letters, 88(17), 174102. * Manis, G., Aktaruzzaman, M. D., & Sassi, R. (2017). Bubble entropy: An entropy almost free of parameters. IEEE Transactions on Biomedical Engineering, 64(11), 2711-2718. """ # Time-delay embedding info = {"Embedded": complexity_embedding(signal, delay=delay, dimension=dimension)} # Transform embedded into permutations matrix if algorithm == "bubblesort": info["Permutations"] = _bubblesort(info["Embedded"]) else: info["Permutations"] = info["Embedded"].argsort(kind="quicksort") # Count and get unique patterns patterns, info["Uniques"], info["Frequencies"] = np.unique( info["Permutations"], axis=0, return_inverse=True, return_counts=True, ) # Find all possible patterns (not needed for now) # all_symbols = np.array(list(map(np.array, list(itertools.permutations(np.arange(delay * dimension)))))) # Relative Frequency info["Frequencies"] = info["Frequencies"] / info["Frequencies"].sum() return patterns, info
def _bubblesort(embedded): """ Manis, G., Aktaruzzaman, M. D., & Sassi, R. (2017). Bubble entropy: An entropy almost free of parameters. IEEE Transactions on Biomedical Engineering, 64(11), 2711-2718. """ n, n_dim = np.shape(embedded) swaps = np.zeros(n) for y in range(n): for t in range(n_dim - 1): for kk in range(n_dim - t - 1): if embedded[y, kk] > embedded[y, kk + 1]: embedded[y, kk], embedded[y, kk + 1] = embedded[y, kk + 1], embedded[y, kk] swaps[y] += 1 return swaps