Source code for neurokit2.complexity.fractal_sevcik

import numpy as np
import pandas as pd

from ..stats import rescale


[docs] def fractal_sevcik(signal): """**Sevcik Fractal Dimension (SFD)** The SFD algorithm was proposed to calculate the fractal dimension of waveforms by Sevcik (1998). This method can be used to quickly measure the complexity and randomness of a signal. .. note:: Some papers (e.g., Wang et al. 2017) suggest adding ``np.log(2)`` to the numerator, but it's unclear why, so we sticked to the original formula for now. But if you have an idea, please let us know! Parameters ---------- signal : Union[list, np.array, pd.Series] The signal (i.e., a time series) in the form of a vector of values. Returns --------- sfd : float The sevcik fractal dimension. info : dict An empty dictionary returned for consistency with the other complexity functions. See Also -------- fractal_petrosian Examples ---------- .. ipython:: python import neurokit2 as nk signal = nk.signal_simulate(duration=2, frequency=5) sfd, _ = nk.fractal_sevcik(signal) sfd References ---------- * Sevcik, C. (2010). A procedure to estimate the fractal dimension of waveforms. arXiv preprint arXiv:1003.5266. * Kumar, D. K., Arjunan, S. P., & Aliahmad, B. (2017). Fractals: applications in biological Signalling and image processing. CRC Press. * Wang, H., Li, J., Guo, L., Dou, Z., Lin, Y., & Zhou, R. (2017). Fractal complexity-based feature extraction algorithm of communication signals. Fractals, 25(04), 1740008. * Goh, C., Hamadicharef, B., Henderson, G., & Ifeachor, E. (2005, June). Comparison of fractal dimension algorithms for the computation of EEG biomarkers for dementia. In 2nd International Conference on Computational Intelligence in Medicine and Healthcare (CIMED2005). """ # Sanity checks if isinstance(signal, (np.ndarray, pd.DataFrame)) and signal.ndim > 1: raise ValueError( "Multidimensional inputs (e.g., matrices or multichannel data) are not supported yet." ) # 1. Normalize the signal (new range to [0, 1]) y_ = rescale(signal, to=[0, 1]) n = len(y_) # 2. Derive x* and y* (y* is actually the normalized signal) x_ = np.linspace(0, 1, n) # 3. Compute L (because we use np.diff, hence n-1 below) L = np.sum(np.sqrt(np.diff(y_) ** 2 + np.diff(x_) ** 2)) # 4. Compute the fractal dimension (approximation) sfd = 1 + np.log(L) / np.log(2 * (n - 1)) # Some papers (e.g., Wang et al. 2017) suggest adding np.log(2) to the numerator: # sfd = 1 + (np.log(L) + np.log(2)) / np.log(2 * (n - 1)) # But it's unclear why. Sticking to the original formula for now. # If you have an idea, let us know! return sfd, {}