import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from ..signal import signal_autocor
[docs]
def complexity_decorrelation(signal, show=False):
"""**Decorrelation Time (DT)**
The decorrelation time (DT) is defined as the time (in samples) of the first zero crossing of
the autocorrelation sequence. A shorter decorrelation time corresponds to a less correlated
signal. For instance, a drop in the decorrelation time of EEG has been observed prior to
seizures, related to a decrease in the low frequency power (Mormann et al., 2005).
Parameters
----------
signal : Union[list, np.array, pd.Series]
The signal (i.e., a time series) in the form of a vector of values.
show : bool
If True, will return a plot of the autocorrelation.
Returns
-------
float
Decorrelation Time (DT)
dict
A dictionary containing additional information (currently empty, but returned nonetheless
for consistency with other functions).
See Also
--------
.signal_autocor
Examples
----------
.. ipython:: python
import neurokit2 as nk
# Simulate a signal
signal = nk.signal_simulate(duration=5, sampling_rate=100, frequency=[5, 6], noise=0.5)
# Compute DT
@savefig p_complexity_decorrelation1.png scale=100%
dt, _ = nk.complexity_decorrelation(signal, show=True)
@suppress
plt.close()
dt
References
----------
* Mormann, F., Kreuz, T., Rieke, C., Andrzejak, R. G., Kraskov, A., David, P., ... & Lehnertz,
K. (2005). On the predictability of epileptic seizures. Clinical neurophysiology, 116(3),
569-587.
* Teixeira, C. A., Direito, B., Feldwisch-Drentrup, H., Valderrama, M., Costa, R. P.,
Alvarado-Rojas, C., ... & Dourado, A. (2011). EPILAB: A software package for studies on the
prediction of epileptic seizures. Journal of Neuroscience Methods, 200(2), 257-271.
"""
# 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."
)
# Unbiased autocor (see https://github.com/mne-tools/mne-features/)
autocor, _ = signal_autocor(signal, unbiased=True)
# Get zero-crossings
zc = np.diff(np.sign(autocor)) != 0
if np.any(zc):
dt = np.argmax(zc) + 1
else:
dt = -1
if show is True:
# Max length of autocorrelation to plot
max_len = int(dt * 4)
if max_len > len(autocor):
max_len = len(autocor)
plt.plot(autocor[0:max_len])
plt.xlabel("Lag")
plt.ylabel("Autocorrelation")
plt.xticks(np.arange(0, max_len, step=dt).astype(int))
plt.axvline(dt, color="red", linestyle="--", label=f"DT = {dt}")
plt.axhline(0, color="black", linestyle="--")
plt.title("Decorrelation Time (DT)")
plt.legend()
return dt, {}