Skip to content

Commit ac72278

Browse files
committed
bugfixes of RQA functions and sorteddistances
1 parent 86f5789 commit ac72278

File tree

5 files changed

+47
-20
lines changed

5 files changed

+47
-20
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ os:
55
- osx
66
julia:
77
- 0.6
8+
- 0.7
89
- nightly
910
branches:
1011
- only:
1112
- master
12-
- julia_0.1_support
1313
matrix:
1414
allow_failures:
1515
- julia: nightly
16-
- branches: julia_0.1_support
1716
notifications:
1817
email: false
1918
# uncomment the following lines to override the default test script

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# RecurrenceAnalysis.jl News
22

3+
## 31-07-2018 - v0.2.1
4+
5+
* Bugfixes:
6+
- `sorteddistances`
7+
- RQA functions (bugs in parameters of diagonal structures when `theiler==0`)
8+
39
## 23-06-2018 - v0.2.0
410

511
* Update to support Julia 0.6-0.7 (breaking compatibility with 0.5).

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ In some cases, specially with very long time series, it may be suitable to perfo
141141
```julia
142142
@windowed determinism(rmat, theiler=2, lmin=3) width=1000 step=100
143143
```
144-
will return a 91-element vector, such that each value is the determinism associated to a 1000-point fragment, starting at every 100 points (i.e. at `1`, `101`, &ldots; `9001`).
144+
will return a 91-element vector, such that each value is the determinism associated to a 1000-point fragment, starting at every 100 points (i.e. at `1`, `101`, … `9001`).
145145

146146
The general syntax of that macro is:
147147
```julia
@@ -154,7 +154,7 @@ where:
154154
* `w` is the width of the window for relevant data around each point.
155155
* `s` is the step or distance between points where the calculations are done (starting in the first point).
156156

157-
To prevent syntax failures in the expansion of the macro, identify the RQA function (`rqa`, `recurrencerate`, `determinism`,&ldots;) directly by its name (avoid aliases), and use simple variable names (not complex expressions) for the arguments. On the other hand, the windowing options `w` and `s` can be given in any order. If `s` is ommitted, the calculations are done at every point, and the keyword `width` may be ommitted. (However, using `step=1` may be computationally very expensive, and that will provide just overly redundant results around each point, so it is advisable to set `step` a relatively big fraction of the window `width`.)
157+
To prevent syntax failures in the expansion of the macro, identify the RQA function (`rqa`, `recurrencerate`, `determinism`,…) directly by its name (avoid aliases), and use simple variable names (not complex expressions) for the arguments. On the other hand, the windowing options `w` and `s` can be given in any order. If `s` is ommitted, the calculations are done at every point, and the keyword `width` may be ommitted. (However, using `step=1` may be computationally very expensive, and that will provide just overly redundant results around each point, so it is advisable to set `step` a relatively big fraction of the window `width`.)
158158

159159
The value returned by the macro will normally be a vector with the same type of numbers as expected by `expr`. In the case of `@windowed rqa(...) ...`, it will return a dictionary with a similar structure as in the default `rqa` function, but replacing scalar values by vectors.
160160

src/radius.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The keyword arguments are the same that should be passed to the functions
2424
`rmat = recurrencematrix(x, d[i]; kwargs...)`, then
2525
`recurrencerate(rmat; kwargs...) == r[i]`.
2626
"""
27-
function sorteddistances(x; theiler::Integer=0, scale=maximum, kwargs...)
27+
function sorteddistances(x; theiler::Integer=0, scale=1, kwargs...)
2828
# Create distance matrix
2929
kwargs = Dict(kwargs)
3030
argsdm = haskey(kwargs,:metric) ? (x, kwargs[:metric]) : (x,)
@@ -37,9 +37,9 @@ function sorteddistances(x; theiler::Integer=0, scale=maximum, kwargs...)
3737
ntheiler = theiler*n - theiler*(theiler-1)/2
3838
distarray = zeros(round(Integer,nd-ntheiler))
3939
pos = 0
40-
for d = theiler:n-1
41-
tmp = dm[n*d+1 : n+1 : n^2]
42-
distarray[pos .+ (1:length(tmp))] = tmp
40+
for d = 1:n
41+
tmp = dm[d+theiler:n,d]
42+
distarray[pos .+ (1:length(tmp))] .= tmp
4343
pos += length(tmp)
4444
end
4545
sort(distarray), (1.:length(distarray))/length(distarray)

src/rqa.jl

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Calculate the recurrence rate (RR) of a recurrence matrix, ruling out
77
the points within the Theiler window.
88
"""
99
function recurrencerate(x::AbstractMatrix; theiler::Integer=0, kwargs...)
10-
theiler < 0 && error("Theiler window length must be greater than 0")
10+
theiler < 0 && error("Theiler window length must be greater than or equal to 0")
1111
if theiler == 0
1212
return typeof(0.0)( count(!iszero, x)/prod(size(x)) )
1313
end
@@ -23,13 +23,13 @@ end
2323

2424
function tau_recurrence(x::AbstractMatrix{Bool})
2525
n = minimum(size(x))
26-
[count(!iszero, diag(x,d))/(n-d) for d in (1:n-1)]
26+
[count(!iszero, diag(x,d))/(n-d) for d in (0:n-1)]
2727
end
2828

2929
# Based on diagonal lines
3030

3131
function diagonalhistogram(x::AbstractMatrix{Bool}; theiler::Integer=1, kwargs...)
32-
theiler < 0 && error("Theiler window length must be greater than 0")
32+
theiler < 0 && error("Theiler window length must be greater than or equal to 0")
3333
bins = [0]
3434
nbins = 1
3535
current_diag = 0
@@ -70,19 +70,35 @@ function diagonalhistogram(x::AbstractMatrix{Bool}; theiler::Integer=1, kwargs..
7070
end
7171

7272
function diagonalhistogram(x::SparseMatrixCSC{Bool}; theiler::Integer=1, kwargs...)
73-
theiler < 0 && error("Theiler window length must be greater than 0")
73+
theiler < 0 && error("Theiler window length must be greater than or equal to 0")
7474
m,n=size(x)
7575
rv = rowvals(x)
7676
dv = colvals(x) - rowvals(x)
77+
loi_hist = Int[]
7778
if issymmetric(x)
78-
valid = (dv .>= theiler)
79+
valid = (dv .>= max(theiler,1))
7980
f = 2
81+
# If theiler==0, the LOI is counted separately to avoid duplication
82+
if theiler == 0
83+
loi_hist = verticalhistogram(hcat(diag(x,0)))
84+
end
8085
else
8186
valid = (abs.(dv) .>= theiler)
8287
f = 1
8388
end
8489
vmat = sparse(rv[valid], dv[valid] .+ (m+1), true)
85-
f .* verticalhistogram(vmat)
90+
dh = f .* verticalhistogram(vmat)
91+
# Add frequencies of LOI if suitable
92+
if (nbins_loi = length(loi_hist)) > 0
93+
nbins = length(dh)
94+
if nbins_loi > nbins
95+
loi_hist[1:nbins] .+= dh
96+
dh = loi_hist
97+
else
98+
dh[1:nbins_loi] .+= loi_hist
99+
end
100+
end
101+
dh
86102
end
87103

88104
"""
@@ -93,7 +109,7 @@ the points within the Theiler window and diagonals shorter than a minimum value.
93109
"""
94110
function determinism(diag_hist::Vector; lmin=2, kwargs...)
95111
if lmin < 2
96-
error("lmin must be 2 or higher")
112+
error("lmin must be 2 or greater")
97113
end
98114
nbins = length(diag_hist)
99115
diag_points = collect(1:nbins) .* diag_hist
@@ -112,7 +128,7 @@ the points within the Theiler window and diagonals shorter than a minimum value.
112128
"""
113129
function avgdiag(diag_hist::Vector; lmin=2, kwargs...)
114130
if lmin < 2
115-
error("lmin must be 2 or higher")
131+
error("lmin must be 2 or greater")
116132
end
117133
nbins = length(diag_hist)
118134
diag_points = collect(1:nbins) .* diag_hist
@@ -148,7 +164,7 @@ the points within the Theiler window and diagonals shorter than a minimum value.
148164
"""
149165
function entropy(diag_hist::Vector; lmin=2, kwargs...)
150166
if lmin < 2
151-
error("lmin must be 2 or higher")
167+
error("lmin must be 2 or greater")
152168
end
153169
nbins = length(diag_hist)
154170
if lmin <= nbins
@@ -173,9 +189,10 @@ the points within the Theiler window and in the outermost diagonals.
173189
function trend(npoints::Vector; theiler=1, border=10, kwargs...)
174190
nmax = length(npoints)
175191
rrk = npoints./collect(nmax:-1:1)
176-
m = nmax-border
177-
w = collect(theiler:m) .- m/2
178-
typeof(0.0)( (w'*(rrk[theiler:m] .- mean(rrk[theiler:m])) ./ (w'*w))[1] )
192+
a = 1+theiler
193+
b = nmax-border
194+
w = collect(a:b) .- b/2
195+
typeof(0.0)( (w'*(rrk[a:b] .- mean(rrk[a:b])) ./ (w'*w))[1] )
179196
end
180197

181198
function trend(x::AbstractMatrix; kwargs...)
@@ -294,6 +311,11 @@ maxvert(x::AbstractMatrix) = maxvert(verticalhistogram(x))
294311

295312
"""
296313
rqa(x; <keyword arguments>)
314+
315+
Calculate RQA parameters of a recurrence matrix. See the functions
316+
`recurrencerate`, `determinism`, `avgdiag`, `maxdiag`, `divergence`, `entropy`,
317+
`trend`, `laminarity`, `trappingtime` and `maxvert` for the definition of
318+
the different parameters and the default values of the arguments.
297319
"""
298320
function rqa(x; kwargs...)
299321
dhist = diagonalhistogram(x; kwargs...)

0 commit comments

Comments
 (0)