antropy.perm_entropy

antropy.perm_entropy(x, order=3, delay=1, normalize=False)[source]

Permutation Entropy.

Parameters
xlist or np.array

One-dimensional time series of shape (n_times)

orderint

Order of permutation entropy. Default is 3.

delayint, list, np.ndarray or range

Time delay (lag). Default is 1. If multiple values are passed (e.g. [1, 2, 3]), AntroPy will calculate the average permutation entropy across all these delays.

normalizebool

If True, divide by log2(order!) to normalize the entropy between 0 and 1. Otherwise, return the permutation entropy in bit.

Returns
pefloat

Permutation Entropy.

Notes

The permutation entropy is a complexity measure for time-series first introduced by Bandt and Pompe in 2002.

The permutation entropy of a signal \(x\) is defined as:

\[H = -\sum p(\pi)\log_2(\pi)\]

where the sum runs over all \(n!\) permutations \(\pi\) of order \(n\). This is the information contained in comparing \(n\) consecutive values of the time series. It is clear that \(0 ≤ H (n) ≤ \log_2(n!)\) where the lower bound is attained for an increasing or decreasing sequence of values, and the upper bound for a completely random system where all \(n!\) possible permutations appear with the same probability.

The embedded matrix \(Y\) is created by:

\[y(i)=[x_i,x_{i+\text{delay}}, ...,x_{i+(\text{order}-1) * \text{delay}}]\]
\[Y=[y(1),y(2),...,y(N-(\text{order}-1))*\text{delay})]^T\]

References

Bandt, Christoph, and Bernd Pompe. “Permutation entropy: a natural complexity measure for time series.” Physical review letters 88.17 (2002): 174102.

Examples

Permutation entropy with order 2

>>> import numpy as np
>>> import antropy as ant
>>> import stochastic.processes.noise as sn
>>> x = [4, 7, 9, 10, 6, 11, 3]
>>> # Return a value in bit between 0 and log2(factorial(order))
>>> print(f"{ant.perm_entropy(x, order=2):.4f}")
0.9183

Normalized permutation entropy with order 3

>>> # Return a value comprised between 0 and 1.
>>> print(f"{ant.perm_entropy(x, normalize=True):.4f}")
0.5888

Fractional Gaussian noise with H = 0.5, averaged across multiple delays >>> rng = np.random.default_rng(seed=42) >>> x = sn.FractionalGaussianNoise(hurst=0.5, rng=rng).sample(10000) >>> print(f”{ant.perm_entropy(x, delay=[1, 2, 3], normalize=True):.4f}”) 0.9999

Fractional Gaussian noise with H = 0.1, averaged across multiple delays

>>> rng = np.random.default_rng(seed=42)
>>> x = sn.FractionalGaussianNoise(hurst=0.1, rng=rng).sample(10000)
>>> print(f"{ant.perm_entropy(x, delay=[1, 2, 3], normalize=True):.4f}")
0.9986

Random

>>> rng = np.random.default_rng(seed=42)
>>> print(f"{ant.perm_entropy(rng.random(1000), normalize=True):.4f}")
0.9997

Pure sine wave

>>> x = np.sin(2 * np.pi * 1 * np.arange(3000) / 100)
>>> print(f"{ant.perm_entropy(x, normalize=True):.4f}")
0.4463

Linearly-increasing time-series

>>> x = np.arange(1000)
>>> print(f"{ant.perm_entropy(x, normalize=True):.4f}")
-0.0000