Skip to content

Commit

Permalink
Added documentation on multifractily. Ready for new release.
Browse files Browse the repository at this point in the history
  • Loading branch information
LRydin committed Jan 19, 2021
1 parent 2a51c20 commit 8f471a8
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 15 deletions.
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
Multifractal Detrended Fluctuation Analysis `MFDFA` is a model-independent method to uncover the self-similarity of a stochastic process or auto-regressive model.
`DFA` was first developed by Peng *et al.*<sup>1</sup> and later extended to study multifractality `MFDFA` by Kandelhardt *et al.*<sup>2</sup>.

In the latest release there is as well added a moving window system, especially useful for short timeseries, a recent extension to DFA called *extended DFA*, and the extra feature of Empirical Mode Decomposition as detrending method.

# Installation
To install MFDFA you can simply use

Expand All @@ -29,6 +31,8 @@ There is an added library `fgn` to generate fractional Gaussian noise.
# Employing the `MFDFA` library

## An exemplary one-dimensional fractional Ornstein–Uhlenbeck process
The rationale here is simple: Numerically integrate a stochastic process in which we know exactly the fractal properties, characterised by the Hurst coefficient, and recover this with MFDFA.
We will use a fractional Ornstein–Uhlenbeck, a commonly employ stochastic process with mean-reverting properties.
For a more detailed explanation on how to integrate an Ornstein–Uhlenbeck process, see the [kramersmoyal's package](https://github.com/LRydin/KramersMoyal#a-one-dimensional-stochastic-process).
You can also follow the [fOU.ipynb](/examples/fOU.ipynb)

Expand Down Expand Up @@ -70,7 +74,7 @@ To now utilise the `MFDFA`, we take this exemplary process and run the (multifra
```python
# Select a band of lags, which usually ranges from
# very small segments of data, to very long ones, as
lag = np.logspace(0.7, 4, 30).astype(int)
lag = np.unique(np.logspace(0.5, 3, 100).astype(int))
# Notice these must be ints, since these will segment
# the data into chucks of lag size

Expand Down Expand Up @@ -98,16 +102,14 @@ np.polyfit(np.log(lag[:15]), np.log(dfa[:15]),1)[0]
# Now what you should obtain is: slope = H + 1
```

<img src="/other/fig1.png" title="MFDFA of a fractional Ornstein–Uhlenbeck process" height="250"/>
<img src="docs/_static/fig1.png" title="MFDFA of a fractional Ornstein–Uhlenbeck process" height="250"/>


## Uncovering multifractality in stochastic processes
`MFDFA`, as an extension to `DFA`, was developed to uncover if a given process is mono or multi fractal.
Let `Xₜ` be a multi fractal stochastic process. This mean `Xₜ` scales with some function alpha(t) as `Xcₜ = |c|alpha(t) Xₜ`.
With the help of taking different powers variations of the `DFA`, one we can distinguish monofractal and multifractal processes.
You can find more about multifractality in the [documentation](https://mfdfa.readthedocs.io/en/latest/1dLevy.html).

# Changelog
- Version 0.4 - EMD is now optional. Restored back compatibility: py3.3 to py3.9
- Version 0.4 - EMD is now optional. Restored back compatibility: py3.3 to py3.9. For EMD py3.6 or larger is needed.
- Version 0.3 - Adding EMD detrending. First release. PyPI code.
- Version 0.2 - Removed experimental features. Added documentation
- Version 0.1 - Uploaded initial working code
Expand All @@ -122,7 +124,7 @@ This package abides to a [Conduct of Fairness](contributions.md).
This library has been submitted for publication at [The Journal of Open Source Software](https://joss.theoj.org/) in December 2019. It was rejected. The review process can be found [here on GitHub](https://github.com/openjournals/joss-reviews/issues/1966). The plan is to extend the library and find another publisher.

### History
This project was started in 2019 at the [Faculty of Mathematics, University of Oslo](https://www.mn.uio.no/math/english/research/groups/risk-stochastics/) in the Risk and Stochastics section by Leonardo Rydin Gorjão and is supported by Dirk Witthaut and the [Institute of Energy and Climate Research Systems Analysis and Technology Evaluation](https://www.fz-juelich.de/iek/iek-ste/EN/Home/home_node.html). I'm very thankful to all the folk in Section 3 in the Faculty of Mathematics, University of Oslo, for helping me getting around the world of stochastic processes: Dennis, Anton, Michele, Fabian, Marc, Prof. Benth and Prof. di Nunno. In April 2020 Galib Hassan joined in extending `MFDFA`, particularly the implementation of EMD.
This project was started in 2019 at the [Faculty of Mathematics, University of Oslo](https://www.mn.uio.no/math/english/research/groups/risk-stochastics/) in the Risk and Stochastics section by Leonardo Rydin Gorjão and is supported by Dirk Witthaut and the [Institute of Energy and Climate Research Systems Analysis and Technology Evaluation](https://www.fz-juelich.de/iek/iek-ste/EN/Home/home_node.html). I'm very thankful to all the folk in Section 3 in the Faculty of Mathematics, University of Oslo, for helping me getting around the world of stochastic processes: Dennis, Anton, Michele, Fabian, Marc, Prof. Benth and Prof. di Nunno. In April 2020 Galib Hassan joined in extending `MFDFA`, particularly the implementation of `EMD`.


### Funding
Expand Down
47 changes: 47 additions & 0 deletions docs/1dLevy.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
Multifractality in one dimensional distributions
================================================

To show how multifractality can be studied, let us take a sample of random numbers of a symmetric `Lévy distribution <https://en.wikipedia.org/wiki/L%C3%A9vy_distribution>`_.


Univariate random numbers from a Lévy stable distribution
---------------------------------------------------------

To obtain a sample of random numbers of Lévy stable distributions, use `scipy`'s `levy_stable`. In particular, take an :math:`\alpha`-stable distribution, with :math:`\alpha=1.5`

.. code:: python
# Imports
from MFDFA import MFDFA
from scipy.stats import levy_stable
# Generate 100000 points
alpha = 1.5
X = levy_stable.rvs(alpha=alpha, beta = 0, size=10000)
For :code:`MFDFA` to detect the multifractal spectrum of the data, we need to vary the parameter :math:`q\in[-10,10]` and exclude :math:`0`. Let us also use a quadratic polynomial fitting by setting :code:`order=2`

.. code:: python
# Select a band of lags, which are ints
lag = np.unique(np.logspace(0.5, 3, 100).astype(int))
# Select a list of powers q
q_list = np.linspace(-10,10,41)
q_list = q_list[q_list!=0.0]
# The order of the polynomial fitting
order = 2
# Obtain the (MF)DFA as
lag, dfa = MFDFA(y, lag = lag, q = q_list, order = order)
Again, we plot this in a double logarithmic scale, but now we include 6 curves, from 6 selected :math:`q={-10,-5-2,2,5,10}`. Include as well are the theoretical curves for :math:`q=-10`, with a slope of :math:`1/\alpha=1/1.5` and :math:`q=10`, with a slope of :math:`1/q=1/10`


.. image:: /_static/fig2.png
:height: 450
:align: center
:alt: Plot of the MFDFA of a Lévy stable distribution for a few q values.
2 changes: 1 addition & 1 deletion docs/1dprocess.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ To now utilise the :code:`MFDFA`, we take this exemplary process and run the (mu
# Select a band of lags, which usually ranges from
# very small segments of data, to very long ones, as
lag = np.logspace(0.7, 4, 30).astype(int)
lag = np.unique(np.logspace(0.5, 3, 100).astype(int))
# Notice these must be ints, since these will segment
# the data into chucks of lag size
Expand Down
Binary file modified docs/_static/fig1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/fig2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
# -- Project information -----------------------------------------------------

project = 'MFDFA'
copyright = '2019-2020 Leonardo Rydin'
copyright = '2019-2021 Leonardo Rydin'
author = 'Leonardo Rydin'

# The full version, including alpha/beta/rc tags
release = '0.3'
version = '0.3'
release = '0.4'
version = '0.4'


# -- General configuration ---------------------------------------------------
Expand Down Expand Up @@ -89,7 +89,7 @@
'style_external_links': False,
'style_nav_header_background': 'black',
# Toc options
'collapse_navigation': True,
'collapse_navigation': False,
'sticky_navigation': True,
'navigation_depth': 4,
'titles_only': False
Expand Down
4 changes: 4 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ MFDFA's documentation

.. include:: 1dprocess.rst

.. include:: 1dLevy.rst

.. include:: extensions.rst

Literature
Expand All @@ -30,9 +32,11 @@ Table of Content

.. toctree::
:maxdepth: 3
:hidden:

installation
1dprocess
1dLevy
extensions
functions/index
license
Binary file removed other/fig1.png
Binary file not shown.
7 changes: 4 additions & 3 deletions tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from numpy.polynomial.polynomial import polyfit
import matplotlib.pyplot as plt

import MFDFA as MFDFA
from MFDFA import MFDFA
from MFDFA import fgn

# %% Lets take a fractional Ornstein–Uhlenbeck process Xₜ with a time-dependent
# diffusion or volatility σₜ, some drift of mean reverting term θ(Xₜ), and
Expand Down Expand Up @@ -31,7 +32,7 @@
H = 0.5

# Generate the fractional Gaussian noise
dw = (t_final ** H) * MFDFA.fgn(time.size, H = H)
dw = (t_final ** H) * fgn(time.size, H = H)

# Integrate the process
for i in range(1,time.size):
Expand All @@ -49,7 +50,7 @@
q = 2

# dfa records the fluctuation function using the EMD as a detrending mechanims.
lag, dfa, dfa_std, e_dfa = MFDFA.MFDFA(X, lag, q = q, order = 1, stat = True, extensions = {"eDFA": True})
lag, dfa, dfa_std, e_dfa = MFDFA(X, lag, q = q, order = 1, stat = True, extensions = {"eDFA": True})

# %% Plots
# Visualise the results in a log-log plot
Expand Down

0 comments on commit 8f471a8

Please sign in to comment.