Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add lombscargle based surrogate for irregular ts #67

Merged
merged 8 commits into from
Jan 16, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@ version = "1.0.0"
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
DelayEmbeddings = "5732040d-69e3-5649-938a-b6b4f237613f"
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
InplaceOps = "505f98c9-085e-5b2c-8e89-488be7bf1f34"
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
LombScargle = "fc60dff9-86e7-5f2f-a8a0-edeadbb75bd9"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
Wavelets = "29a6e085-ba6d-5f35-a997-948ac2efa89a"

[compat]
AbstractFFTs = "= 0.4.1, 0.5"
DelayEmbeddings = "1.5.1"
DSP = "^0.5.2, 0.6, ^1"
DelayEmbeddings = "1.5.1"
Distributions = "0.21, 1, 0.23"
InplaceOps = "^0.3.0, ^1"
Interpolations = "^0.12, ^1"
Expand Down
4 changes: 4 additions & 0 deletions src/TimeseriesSurrogates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module TimeseriesSurrogates
# the global usage here. It makes it easier to understand how each algorithm works
# and what it needs
using Distributions
using Distances # Will be used by the LombScargle method
using StatsBase
using InplaceOps
using AbstractFFTs
Expand All @@ -29,6 +30,9 @@ include("methods/truncated_fourier.jl")
include("methods/wavelet_based.jl")
include("methods/pseudoperiodic.jl")

# Methods for irregular time series
include("methods/lombscargle.jl")

# Visualization routine for time series + surrogate + periodogram/acf/histogram
using Requires
function __init__()
Expand Down
11 changes: 11 additions & 0 deletions src/api.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,14 @@ function surrogate(x, method::Surrogate)
sg = surrogenerator(x, method)
sg()
end

"""
surrogate(x,t, method::Surrogate) → s
felixcremer marked this conversation as resolved.
Show resolved Hide resolved
Create a single timeseries `s` from the irregular time series `x` with time steps `t`
based on the given `method`.
If you want to generate more than one surrogate from `x`, you should use a [`surrogenerator`](@ref)
"""
function surrogate(x, t, method::Surrogate)
felixcremer marked this conversation as resolved.
Show resolved Hide resolved
sg = surrogenerator(x,t,method)
sg()
end
60 changes: 60 additions & 0 deletions src/methods/lombscargle.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using LombScargle

export LS
"""

Compute a surrogate of the irregular time series x with supporting time steps t
based on the simulated annealing method described in

Testing for nonlinearity in unevenly sampled time seriesAndreas Schmitz and Thomas Schreiber
"""
struct LS <: Surrogate end

function loss(ls1, signal2,taxis;q=1)
#lsplan1 = LombScargle.plan(taxis, signal1)
lsplan2 = LombScargle.plan(taxis, signal2)
#ls1 = lombscargle(lsplan1)
ls2 = lombscargle(lsplan2)
#@show ls1.power .- ls2.power
return minkowski(ls1.power, ls2.power,q)
end



function surrogate(signal,taxis,sg::LS; N_total=10000, N_acc=2000, tol=1)
felixcremer marked this conversation as resolved.
Show resolved Hide resolved
n = length(signal)
surr = surrogate(signal, RandomShuffle())
lsorg = lombscargle(taxis, signal)
lossold = loss(lsorg,surr, taxis)
i = j = 1
while i < N_total && j<N_acc
if mod(i,500) ==0
@show i, j,lossold
end
k,l = sample(1:n,2, replace=false)
#@show k,l
newsurr = copy(surr)
newsurr[[k,l]] = surr[[l,k]]
lossnew = loss(lsorg, newsurr, taxis)
if lossnew < lossold
lossnew <= tol && break
#@show "update"
surr, lossold = newsurr, lossnew
j += 1
#=else
## Implement drawing with a probability p
lossdiff = lossnew - lossold
@show lossdiff
T = 1
p = exp(-lossdiff/log(i)) # Where does T come from?
if rand() < p
@show p
surr, lossold = newsurr, lossnew
j += 1
end
=#
end
i+=1
end
return surr
end