antropy.detrended_fluctuation

antropy.detrended_fluctuation(x)[source]

Detrended fluctuation analysis (DFA).

Parameters:
xlist or np.array

One-dimensional time-series.

Returns:
alphafloat

the estimate alpha (\(\alpha\)) for the Hurst parameter.

\(\alpha < 1`\) indicates a stationary process similar to fractional Gaussian noise with \(H = \alpha\).

\(\alpha > 1`\) indicates a non-stationary process similar to fractional Brownian motion with \(H = \alpha - 1\)

Notes

Detrended fluctuation analysis is used to find long-term statistical dependencies in time series.

The idea behind DFA originates from the definition of self-affine processes. A process \(X\) is said to be self-affine if the standard deviation of the values within a window of length n changes with the window length factor \(L\) in a power law:

\[\text{std}(X, L * n) = L^H * \text{std}(X, n)\]

where \(\text{std}(X, k)\) is the standard deviation of the process \(X\) calculated over windows of size \(k\). In this equation, \(H\) is called the Hurst parameter, which behaves indeed very similar to the Hurst exponant.

For more details, please refer to the excellent documentation of the nolds Python package by Christopher Scholzel, from which this function is taken: https://cschoel.github.io/nolds/nolds.html#detrended-fluctuation-analysis

Note that the default subseries size is set to entropy.utils._log_n(4, 0.1 * len(x), 1.2)). The current implementation does not allow to manually specify the subseries size or use overlapping windows.

The code is a faster (Numba) adaptation of the original code by Christopher Scholzel.

References

  • C.-K. Peng, S. V. Buldyrev, S. Havlin, M. Simons, H. E. Stanley, and A. L. Goldberger, “Mosaic organization of DNA nucleotides,” Physical Review E, vol. 49, no. 2, 1994.

  • R. Hardstone, S.-S. Poil, G. Schiavone, R. Jansen, V. V. Nikulin, H. D. Mansvelder, and K. Linkenkaer-Hansen, “Detrended fluctuation analysis: A scale-free view on neuronal oscillations,” Frontiers in Physiology, vol. 30, 2012.

Examples

Fractional Gaussian noise with H = 0.5

>>> import numpy as np
>>> import antropy as ant
>>> import stochastic.processes.noise as sn
>>> rng = np.random.default_rng(seed=42)
>>> x = sn.FractionalGaussianNoise(hurst=0.5, rng=rng).sample(10000)
>>> print(f"{ant.detrended_fluctuation(x):.4f}")
0.5216

Fractional Gaussian noise with H = 0.9

>>> rng = np.random.default_rng(seed=42)
>>> x = sn.FractionalGaussianNoise(hurst=0.9, rng=rng).sample(10000)
>>> print(f"{ant.detrended_fluctuation(x):.4f}")
0.8833

Fractional Gaussian noise with H = 0.1

>>> rng = np.random.default_rng(seed=42)
>>> x = sn.FractionalGaussianNoise(hurst=0.1, rng=rng).sample(10000)
>>> print(f"{ant.detrended_fluctuation(x):.4f}")
0.1262

Random

>>> rng = np.random.default_rng(seed=42)
>>> print(f"{ant.detrended_fluctuation(rng.random(1000)):.4f}")
0.5276

Pure sine wave

>>> x = np.sin(2 * np.pi * 1 * np.arange(3000) / 100)
>>> print(f"{ant.detrended_fluctuation(x):.4f}")
1.5848

Linearly-increasing time-series

>>> x = np.arange(1000)
>>> print(f"{ant.detrended_fluctuation(x):.4f}")
2.0390