# 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:

1. N. Marwan et al., "Recurrence plots for the analysis of complex systems", Phys. Reports 438(5-6), 237-329 (2007).
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).

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.rqaFunction
rqa(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.):

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 types RecurrenceMatrix or JointRecurrenceMatrix, but it is included for matrices of the type CrossRecurrenceMatrix. 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 the n central diagonals are excluded (at both sides of the LOI, i.e. actually 2n-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 as rqa(R...))
• rqa(DT,R...) to obtain the output as DT which is a subtype of AbstractDict (e.g. rqa(OrderedDict,R...) returns an OrderedDict)

Return values for empty histograms

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:

1. Quantities that represent maximum or average values are 0.0.
2. Quantities that represent entropies are NaN.

See also the @windowed macro for a windowed version of rqa.

### Classical RQA Measures

RecurrenceAnalysis.recurrencerateFunction
recurrencerate(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.determinismFunction
determinism(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_averageFunction
dl_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_maxFunction
dl_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_entropyFunction
dl_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).

RecurrenceAnalysis.trendFunction
trend(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.laminarityFunction
laminarity(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.trappingtimeFunction
trappingtime(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_averageFunction
vl_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_maxFunction
vl_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_entropyFunction
vl_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).

### Recurrence Time Measures

RecurrenceAnalysis.meanrecurrencetimeFunction
meanrecurrencetime(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.nmprtFunction
nmprt(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_entropyFunction
rt_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).

RecurrenceAnalysis.rt_averageFunction
rt_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:

ArgumentDefaultFunctionsDescription
theiler0 for CrossRecurrenceMatrix, 1 otherwise.recurrencerate<br/>determinism<br/>*_average<br/>*_max<br/>*_entropy<br/>divergence<br/>trend<br/>laminarity<br/>trappingtime<br/> meanrecurrencetime<br/>nmprtTheiler 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.
lmin2determinism<br/>*_average<br/>*_max<br/>*_entropy<br/>divergence<br/>laminarity<br/>trappingtime<br/> meanrecurrencetime<br/>nmprtMinimum length of the recurrent structures (diagonal or vertical) considered in the analysis.
border10trendNumber 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.recurrencestructuresFunction
recurrencestructures(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).