Recurrence Quantification Analysis
A RecurrenceMatrix
can be analyzed in several ways to yield information about the dynamics of the trajectory. All these various measures and functions are collectively called "Recurrence Quantification Analysis" (RQA).
To understand how each measure can be useful, we suggest to see the review articles listed in our documentation strings, namely:
- N. Marwan et al., "Recurrence plots for the analysis of complex systems", Phys. Reports 438(5-6), 237-329 (2007).
- N. Marwan & C.L. Webber, "Mathematical and computational foundations of recurrence quantifications", in: Webber, C.L. & N. Marwan (eds.), Recurrence Quantification Analysis. Theory and Best Practices, Springer, pp. 3-43 (2015).
You can also check the wikipedia page for Recurrence quantification analysis.
The functions described in this page all accept a recurrence matrix (x
), see RecurrenceMatrix
.
RQA Measures
All-in-one Bundle
In case you need all of the RQA-related functions (see below) and you don't want to write 10 lines of code to compute them all (since they are so many) we provide an all-in-one function that computes all of them and returns a dictionary with the results!
RecurrenceAnalysis.rqa
— Functionrqa(R; kwargs...)
Calculate all RQA parameters of a recurrence matrix R
. See the functions referred to below for the definition of the different parameters and the default values of the arguments. Using this function is much more efficient than calling all individual functions one by one.
Return
The returned value contains the following entries, which can be retrieved as from a dictionary (e.g. results[:RR]
, etc.):
:RR
: recurrence rate (seerecurrencerate
):DET
: determinsm (seedeterminism
):L
: average length of diagonal structures (seedl_average
):Lmax
: maximum length of diagonal structures (seedl_max
):DIV
: divergence (seedivergence
):ENTR
: entropy of diagonal structures (seedl_entropy
):TREND
: trend of recurrences (seetrend
):LAM
: laminarity (seelaminarity
):TT
: trapping time (seetrappingtime
):Vmax
: maximum length of vertical structures (seevl_max
):VENTR
: entropy of vertical structures (seevl_entropy
):MRT
: mean recurrence time (seemeanrecurrencetime
):RTE
recurrence time entropy (seert_entropy
):NMPRT
: number of the most probable recurrence time (seenmprt
)
All the parameters returned by rqa
are Float64
numbers, even for parameters like :Lmax
, :Vmax
or :NMPRT
which are integer values. In the case of empty histograms (e.g. no existing vertical lines less than the keyword lminvert
) the average and maximum values (:L
, :Lmax
, :TT
, :Vmax
, :MRT
) are returned as 0.0
but their respective entropies (:ENTR
, :VENTR
, :RTE
) are returned as NaN
.
Keyword Arguments
Standard keyword arguments are the ones accepted by the functions listed below, i.e. theiler
, lmin
, and border
:
theiler
is used to define a "Theiler window" around the central diagonal or "line of identity" (LOI): a region of points that are excluded in the calculation of RQA parameters, in order to rule out self-recurrences and apparent recurrences for smooth or high resolution data. The LOI is excluded by default for matrices of the typesRecurrenceMatrix
orJointRecurrenceMatrix
, but it is included for matrices of the typeCrossRecurrenceMatrix
.theiler=0
means that the whole matrix is scanned for lines.theiler=1
means that the LOI is excluded. In general,theiler=n
means that then
central diagonals are excluded (at both sides of the LOI, i.e. actually2n-1
diagonals are excluded).lmin
is used to define the minimum line length in the parameters that describe the distributions of diagonal or vertical lines (it is set as 2 by default).border
is used to avoid border effects in the calculation of:TREND
(cf.trend
).
In addition theilerdiag
, lmindiag
may be used to declare specific values that override the values of theiler
and lmin
in the calculation of parameters related to diagonal structures. Likewise, theilervert
and lminvert
can be used for the calculation of parameters related to vertical structures.
The keyword argument onlydiagonal
(false
by default) can be set to true
in order to restrict the analysis to the recurrence rate and the parameters related to diagonal structures (:RR
, :DET
, :L
, :Lmax
, :DIV
and :ENTR
), which makes this function slightly faster.
Transitional note on the returned type
In older versions, the rqa
function returned a NamedTuple
, and in future versions it is planned to return a Dict
instead. In both cases, the results can be indexed with square brackets and Symbol
keys, as result[:RR]
, result[:DET]
, etc. However, named tuples can also be indexed with "dot syntax", e.g. result.RR
, whereas this will not be possible with dictionaries, and there are other differences in the indexing and iteration of those two types.
In order to facilitate the transition between versions, this function currently returns a RQA
object that essentially works as a dictionary, but can also be indexed with the dot syntax (logging a deprecation warning). The returned type can also be specified as a first argument of rqa
in order to replicate the output of different versions:
rqa(NamedTuple, R...)
to obtain the output of the older version (as in 1.3).rqa(Dict, R...)
to obtain the output of the planned future version.rqa(RQA, R...)
to obtain the default current output (same asrqa(R...)
)rqa(DT,R...)
to obtain the output asDT
which is a subtype ofAbstractDict
(e.g.rqa(OrderedDict,R...)
returns anOrderedDict
)
It may be the case that for a given recurrence matrix some structures do not exist at all. For example there are recurrence matrices that have no vertical lengths (or no vertical lengths with length less than lmin
). In such cases the behavior of our RQA pipeline is the following:
- Quantities that represent maximum or average values are
0.0
. - Quantities that represent entropies are
NaN
.
See also the [windowed
] function for a windowed version of rqa
.
Example
For example, here are the RQA measures for the same example trajectory we used to make Simple Recurrence Plots
using RecurrenceAnalysis, DynamicalSystemsBase
# Create trajectory of Roessler system
@inbounds function roessler_rule(u, p, t)
a, b, c = p
du1 = -u[2]-u[3]
du2 = u[1] + a*u[2]
du3 = b + u[3]*(u[1] - c)
return SVector(du1, du2, du3)
end
p0 = [0.15, 0.2, 10.0]
u0 = ones(3)
ro = CoupledODEs(roessler_rule, u0, p0)
N = 2000; Δt = 0.05
X, t = trajectory(ro, N*Δt; Δt, Ttr = 10.0)
# Make a recurrence matrix with fixed threshold
R = RecurrenceMatrix(X, 5.0)
# Compute RQA measures
rqa(R)
RQA parameters in Dict{Symbol, Float64} with 14 entries:
:DIV => 0.00118624
:LAM => 0.999173
:Vmax => 57.0
:VENTR => 3.57043
:Lmax => 843.0
:MRT => 172.716
:NMPRT => 2467.0
:RR => 0.0953458
:RTE => 3.78882
:TT => 17.9861
:L => 133.317
:ENTR => 5.49263
:DET => 0.999443
:TREND => -0.0228398
Classical RQA Measures
RecurrenceAnalysis.recurrencerate
— Functionrecurrencerate(R[; theiler])
Calculate the recurrence rate of the recurrence matrix R
.
Description
The recurrence rate is calculated as:
\[RR = \frac{1}{S} \sum R\]
where $S$ is the size of R
or the region of R
with potential recurrent points. There is not a unique definition of that denominator, which is defined as the full size of the matrix in many sources (e.g. [1]), whereas in others it is adjusted to remove the points of the LOI when they are excluded from the count [2,3].
For matrices of type RecurrenceMatrix
or JointRecurrenceMatrix
, where the points around the central diagonal are usually excluded, the denominator is adjusted to the size of the matrix outside the Theiler window (by default equal to the LOI, and adjustable with the keyword argument theiler
; see rqa
for details). For matrices of type CrossRecurrenceMatrix
, where normally all points are analyzed, the denominator is always the full size of the matrix, regardless of the Theiler window that might be defined (none by default).
Hint: to reproduce the calculations done following the formulas that use the full size of the matrix in the denominator, use CrossRecurrenceMatrix(s,s,ε)
to define the recurrence matrix, instead of RecurrenceMatrix(s,ε)
, setting theiler=1
(or theiler=n
in general) to explicitly exclude the LOI or other diagonals around it.
References
[1] : N. Marwan et al., "Recurrence plots for the analysis of complex systems", Phys. Reports 438(5-6), 237-329 (2007). DOI:10.1016/j.physrep.2006.11.001
[2] : C.L. Webber & J.P. Zbilut, "Recurrence Quantification Analysis of Nonlinear Dynamical Systems", in: Riley MA & Van Orden GC, Tutorials in Contemporary Nonlinear Methods for the Behavioral Sciences, 26-94 (2005). URL: https://www.nsf.gov/pubs/2005/nsf05057/nmbs/nmbs.pdf
[3] : N. Marwan & C.L. Webber, "Mathematical and computational foundations of recurrence quantifications", in: Webber, C.L. & N. Marwan (eds.), Recurrence Quantification Analysis. Theory and Best Practices, Springer, pp. 3-43 (2015).
RecurrenceAnalysis.determinism
— Functiondeterminism(R[; lmin=2, theiler])
Calculate the determinism of the recurrence matrix R
:
Description
The determinism is calculated as:
\[DET = \frac{\sum_{l=lmin}{l P(l)}}{\sum_{l=1}{l P(l)}} = \frac{\sum_{l=lmin}{l P(l)}}{\sum R}\]
where $l$ stands for the lengths of diagonal lines in the matrix, and $P(l)$ is the number of lines of length equal to $l$.
lmin
is set to 2 by default, and this calculation rules out all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
RecurrenceAnalysis.dl_average
— Functiondl_average(R[; lmin=2, theiler])
Calculate the average of the diagonal lines contained in the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
RecurrenceAnalysis.dl_max
— Functiondl_max(R[; lmin=2, theiler])
Calculate the longest diagonal line contained in the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
RecurrenceAnalysis.dl_entropy
— Functiondl_entropy(R[; lmin=2, theiler])
Calculate the Shannon entropy of the diagonal lines contained in the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
Notes: This metric was first proposed in the paper "Exploiting Nonlinear Recurrence and Fractal Scaling Properties for Voice Disorder Detection" as Recurrence Period Density Entropy or Recurrence Probability Density Entropy (RPDE). It is a normalized dimensionless metric in the range [0,1]. In the 2018 article "Recurrence threshold selection for obtaining robust recurrence characteristics in different embedding dimensions", the indicator RPDE is explicitly called Recurrence Time Entropy (RTE). Here RPDE and RTE are clearly the same indicator.
RecurrenceAnalysis.divergence
— Functiondivergence(R[; theiler])
Calculate the divergence of the recurrence matrix R
(actually the inverse of dl_max
).
RecurrenceAnalysis.trend
— Functiontrend(R[; border=10, theiler])
Calculate the trend of recurrences in the recurrence matrix R
.
Description
The trend is the slope of the linear regression that relates the density of recurrent points in the diagonals parallel to the LOI and the distance between those diagonals and the LOI. It quantifies the degree of system stationarity, such that in recurrence plots where points "fade away" from the central diagonal, the trend will have a negative value.
It is calculated as:
\[TREND = 10^3\frac{\sum_{d=\tau}^{\tilde{N}}\delta[d]\left(RR[d]-\langle RR[d]\rangle\right)}{\sum_{d=\tau}^{\tilde{N}}\delta[d]^2}\]
where $RR[d]$ is the local recurrence rate of the diagonal $d$, $\delta[d]$ is a balanced measure of the distance between that diagonal and the LOI, $\tau$ is the Theiler window (number of central diagonals that are excluded), and $\tilde{N}$ is the number of the outmost diagonal that is included.
This parameter is expressed in units of variation recurrence rate every 1000 data points, hence the factor $10^3$ in the formula [1].
The 10 outermost diagonals (counting from the corners of the matrix) are excluded by default to avoid "border effects". Use the keyword argument border
to define a different number of excluded lines, and theiler
to define the size of the Theiler window (see rqa
for details).
Note: In rectangular cross-recurrence plots (i.e. when the time series that originate them are not of the same length), the limits of the formula for TREND are not clearly defined. For the sake of consistency, this function limits the calculations to the biggest square matrix that contains the LOI.
References
[1] C.L. Webber & J.P. Zbilut, "Recurrence Quantification Analysis of Nonlinear Dynamical Systems", in: Riley MA & Van Orden GC, Tutorials in Contemporary Nonlinear Methods for the Behavioral Sciences, 2005, 26-94. https://www.nsf.gov/pubs/2005/nsf05057/nmbs/nmbs.pdf
Extended RQA Measures
RecurrenceAnalysis.laminarity
— Functionlaminarity(R[; lmin=2, theiler])
Calculate the laminarity of the recurrence matrix R
.
Description
The laminarity is calculated as:
\[LAM = \frac{\sum_{v=lmin}{v P(l)}}{\sum_{v=1}{v P(v)}} = \frac{\sum_{v=lmin}{v P(l)}}{\sum R}\]
where $v$ stands for the lengths of vertical lines in the matrix, and $P(v)$ is the number of lines of length equal to $v$.
lmin
is set to 2 by default, and this calculation rules out all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
RecurrenceAnalysis.trappingtime
— Functiontrappingtime(R[; lmin=2, theiler])
Calculate the trapping time of the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
The trapping time is the average of the vertical line structures and thus equal to vl_average
.
RecurrenceAnalysis.vl_average
— Functionvl_average(R[; lmin=2, theiler])
Calculate the average of the vertical lines contained in the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
RecurrenceAnalysis.vl_max
— Functionvl_max(R[; lmin=2, theiler])
Calculate the longest vertical line contained in the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
RecurrenceAnalysis.vl_entropy
— Functionvl_entropy(R[; lmin=2, theiler])
Calculate the Shannon entropy of the vertical lines contained in the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
Notes: This metric was first proposed in the paper "Exploiting Nonlinear Recurrence and Fractal Scaling Properties for Voice Disorder Detection" as Recurrence Period Density Entropy or Recurrence Probability Density Entropy (RPDE). It is a normalized dimensionless metric in the range [0,1]. In the 2018 article "Recurrence threshold selection for obtaining robust recurrence characteristics in different embedding dimensions", the indicator RPDE is explicitly called Recurrence Time Entropy (RTE). Here RPDE and RTE are clearly the same indicator.
Recurrence Time Measures
RecurrenceAnalysis.meanrecurrencetime
— Functionmeanrecurrencetime(R[; lmin=2, theiler])
Calculate the mean recurrence time of the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
Equivalent to rt_average
.
RecurrenceAnalysis.nmprt
— Functionnmprt(R[; lmin=2, theiler])
Calculate the number of the most probable recurrence time (NMPRT), ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
This number indicates how many times the system has recurred using the recurrence time that appears most frequently, i.e it is the maximum value of the histogram of recurrence times [1].
References
[1] : E.J. Ngamga et al. "Recurrence analysis of strange nonchaotic dynamics", Physical Review E, 75(3), 036222(1-8) (2007) DOI:10.1103/physreve.75.036222
RecurrenceAnalysis.rt_entropy
— Functionrt_entropy(R[; lmin=2, theiler])
Calculate the Shannon entropy of the recurrence times contained in the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
Notes: This metric was first proposed in the paper "Exploiting Nonlinear Recurrence and Fractal Scaling Properties for Voice Disorder Detection" as Recurrence Period Density Entropy or Recurrence Probability Density Entropy (RPDE). It is a normalized dimensionless metric in the range [0,1]. In the 2018 article "Recurrence threshold selection for obtaining robust recurrence characteristics in different embedding dimensions", the indicator RPDE is explicitly called Recurrence Time Entropy (RTE). Here RPDE and RTE are clearly the same indicator.
RecurrenceAnalysis.rt_average
— Functionrt_average(R[; lmin=2, theiler])
Calculate the average of the recurrence times contained in the recurrence matrix R
, ruling out the lines shorter than lmin
(2 by default) and all the points inside the Theiler window (see rqa
for the default values and usage of the keyword argument theiler
).
Keyword table
Since most of the above functions can be fined tuned with keyword arguments, here is a table summarizing them that could be of use:
Argument | Default | Functions | Description |
---|---|---|---|
theiler | 0 for CrossRecurrenceMatrix , 1 otherwise. | recurrencerate , determinism , *_average , *_max , *_entropy , divergence , trend , laminarity , trappingtime , meanrecurrencetime , nmprt | Theiler window: number of diagonals around the LOI excluded from the analysis. The value 0 means that the LOI is included in the analysis. Use 1 to exclude the LOI. |
lmin | 2 | determinism , *_average , *_max , *_entropy , divergence , laminarity , trappingtime , meanrecurrencetime , nmprt | Minimum length of the recurrent structures (diagonal or vertical) considered in the analysis. |
border | 10 | trend | Number of diagonals excluded from the analysis near the border of the matrix. |
Recurrence Structures Histograms
The functions that we list in this page internally compute histograms of some recurrence structures, like e.g. the vertical lengths. You can access these values directly with the following function:
RecurrenceAnalysis.recurrencestructures
— Functionrecurrencestructures(x::AbstractRecurrenceMatrix;
diagonal=true,
vertical=true,
recurrencetimes=true,
kwargs...)
Return a dictionary with the histograms of the recurrence structures contained in the recurrence matrix x
, with the keys "diagonal"
, "vertical"
or "recurrencetimes"
, depending on what keyword arguments are given as true
.
Description
Each item of the dictionary is a vector of integers, such that the i
-th element of the vector is the number of lines of length i
contained in x
.
"diagonal"
counts the diagonal lines, i.e. the recurrent trajectories."vertical"
counts the vertical lines, i.e. the laminar states."recurrencetimes"
counts the vertical distances between recurrent states, i.e. the recurrence times.
All the points of the matrix are counted by default. The keyword argument theiler
can be passed to rule out the lines around the main diagonal. See the arguments of the function rqa
for further details.
"Empty" histograms are represented always as [0]
.
Notice: There is not a unique operational definition of "recurrence times". In the analysis of recurrence plots, usually the "second type" of recurrence times as defined by Gao and Cai [1] are considered, i.e. the distance between consecutive (but separated) recurrent structures in the vertical direction of the matrix. But that distance is not uniquely defined when the vertical recurrent structures are longer than one point. The recurrence times calculated here are the distance between the midpoints of consecutive lines, which is a balanced estimator of the Poincaré recurrence times [2].
References
[1] J. Gao & H. Cai. "On the structures and quantification of recurrence plots". Physics Letters A, 270(1-2), 75–87 (2000).
[2] N. Marwan & C.L. Webber, "Mathematical and computational foundations of recurrence quantifications", in: Webber, C.L. & N. Marwan (eds.), Recurrence Quantification Analysis. Theory and Best Practices, Springer, pp. 3-43 (2015).
Windowed application
RecurrenceAnalysis.windowed
— Functionwindowed(rmat, f, width, step = 1; kwargs...)
A convenience function that applies the RQA function f
, such as determinism
, to windowed views of the given recurrence matrix rmat
with given window width
and step
. The kwargs...
are propagated to the call f(rmat_view; kwargs...)
.