Skip to content

Commit 0e5f2b9

Browse files
authored
Simple autoregressive surrogates (#77)
* initial autoregresive surrogator * add autoregressive codfe * add docstring * runnable code * fix autoregressive length * add AR to the docs * add test for autoregressive * add changelog / increment version * fix forgotten < lol
1 parent 3a75ff3 commit 0e5f2b9

File tree

6 files changed

+67
-1
lines changed

6 files changed

+67
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
*Changelog is kept with respect to version 1.0. This software follows SymVer2.0*
22

3+
# 1.2
4+
New surrogate methods: `AutoRegressive`
35
# 1.1
46
* New surrogate methods: `CycleShuffle`, `ShuffleDimensions`, `CircShift`

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name = "TimeseriesSurrogates"
22
uuid = "c804724b-8c18-5caa-8579-6025a0767c70"
33
authors = ["Kristian Agasøster Haaga <kahaaga@gmail.com>", "George Datseris"]
44
repo = "https://github.com/kahaaga/TimeseriesSurrogates.jl.git"
5-
version = "1.1.1"
5+
version = "1.2.0"
66

77
[deps]
88
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"

docs/src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ TFTS
3232
AAFT
3333
TAAFT
3434
IAAFT
35+
AutoRegressive
3536
PseudoPeriodic
3637
WLS
3738
ShuffleDimensions

src/TimeseriesSurrogates.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ include("methods/truncated_fourier.jl")
2929
include("methods/wavelet_based.jl")
3030
include("methods/pseudoperiodic.jl")
3131
include("methods/multidimensional.jl")
32+
include("methods/ar.jl")
3233

3334
# Visualization routine for time series + surrogate + periodogram/acf/histogram
3435
using Requires

src/methods/ar.jl

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using DSP, Random
2+
export AutoRegressive
3+
4+
"""
5+
AutoRegressive(n, method = LPCLevinson())
6+
7+
Autoregressive surrogates of order-`n`. The autoregressive coefficients `φ` are estimated
8+
using `DSP.lpc(x, n, method)`, and thus see the documentation of DSP.jl for possible
9+
`method`s.
10+
11+
While these surrogates are obviously suited to test the null hypothesis whether the data
12+
are coming from a autoregressive process, the Fourier Transform-based surrogates are
13+
probably a better option. The current method is more like an explicit way to
14+
produce surrogates for the same hypothesis by fitting a model.
15+
It can be used as convient way to estimate
16+
autoregressive coefficients and automatically generate surrogates based on them.
17+
18+
The coefficients φ of the autoregressive fit can be found by doing
19+
```julia
20+
sg = surrogenerator(x, AutoRegressive(n))
21+
φ = sg.init.φ
22+
```
23+
"""
24+
struct AutoRegressive{M} <: Surrogate
25+
n::Int
26+
m::M
27+
end
28+
AutoRegressive(n::Int) = AutoRegressive(n, LPCLevinson())
29+
30+
function surrogenerator(x, method::AutoRegressive)
31+
φ, e = lpc(x, method.n, method.m)
32+
init = (d = Normal(0, std(x)), φ = φ)
33+
return SurrogateGenerator(method, x, init)
34+
end
35+
36+
function (sg::SurrogateGenerator{<:AutoRegressive})()
37+
N, φ, d = length(sg.x), sg.init.φ, sg.init.d
38+
return autoregressive(d, N, φ)
39+
end
40+
41+
function autoregressive(d::Normal{T}, N, φ) where {T}
42+
f = length(φ)
43+
z = zeros(T, N+f)
44+
@inbounds for i in 1:f; z[i] = rand(d); end
45+
@inbounds for i in f+1:length(z)
46+
s = zero(T)
47+
for j in 1:f
48+
s += φ[j]*z[i-j]
49+
end
50+
s += rand(d)
51+
z[i] = s
52+
end
53+
return view(z, f+1:N+f)
54+
end

test/runtests.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ end
4848
@test all([s[i] x for i = 1:N])
4949
end
5050

51+
@testset "AutoRegressive" begin
52+
y = TimeseriesSurrogates.AR1(2000, 0.1, 0.5)
53+
sg = surrogenerator(y, AutoRegressive(1))
54+
@test 0.4 abs(sg.init.φ[1]) 0.6
55+
s = sg()
56+
@test length(s) == length(y)
57+
end
58+
5159
@testset "AAFT" begin
5260
aaft = AAFT()
5361
s = surrogate(x, aaft)

0 commit comments

Comments
 (0)