From 83e3141ca88cac5c841a6b5f22279a7ffb390ae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Agas=C3=B8ster=20Haaga?= Date: Mon, 13 Dec 2021 17:16:52 +0100 Subject: [PATCH 1/7] Exclude some lags --- src/transferentropy/autoutils.jl | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/transferentropy/autoutils.jl b/src/transferentropy/autoutils.jl index 6787248..e119ee5 100644 --- a/src/transferentropy/autoutils.jl +++ b/src/transferentropy/autoutils.jl @@ -18,9 +18,13 @@ the variables. If `maxlag` is an integer, `maxlag` is taken as the maximum allowed embedding lag. If `maxlag` is a float, then the maximum embedding lag is taken as `maximum([length.(source); length.(target); length.(cond)])*maxlag`. + +If `exclude` is an integer, all variables whose embedding lag has absolute value equal to `exclude` will be +removed from the """ function construct_candidate_variables(source, target, cond; - k::Int = 1, + k::Int = 1, + exclude::Union{Int, Nothing} = nothing, include_instantaneous = true, method_delay = "ac_min", maxlag::Union{Int, Float64} = 0.05) @@ -42,6 +46,7 @@ function construct_candidate_variables(source, target, cond; # Generate candidate set startlag = include_instantaneous ? 0 : -1 + τs_source = [[startlag:-1:-τ...,] for τ in τsmax_source] τs_target = [[startlag:-1:-τ...,] for τ in τsmax_target] τs_cond = [[startlag:-1:-τ...,] for τ in τsmax_cond] @@ -54,6 +59,20 @@ function construct_candidate_variables(source, target, cond; return [τs..., ks_targetfuture], [js..., js_targetfuture] end +# Usaully, we use all lags from startlag:-\tau_max. These functions are used to exclude some lags +# in those ranges, if necessary. +exclude_lags(τs::AbstractVector{Int}, js::AbstractVector{Int}, exclude::Int) = + [τ for τ in τs if abs(τ) != abs.(exclude)] + +function exclude_lags(τs::AbstractVector{Int}, js::AbstractVector{Int}, exclude::AbstractVector{Int}) + if isempty(exclude) + return τs + else + return [τ for τ in τs if abs(x) ∉ abs.(exclude)] + end +end +exclude_lags(τs::Vector{AbstractVector{Int}}, exclude) = [exclude_lags(l, exclude) for l in τs] + # source & target variant function construct_candidate_variables(source, target; k::Int = 1, From 72ddcef29bf0df0c18b62b8b3570486c7d4c6287 Mon Sep 17 00:00:00 2001 From: Kristian Haaga Date: Tue, 14 Dec 2021 11:35:10 +0100 Subject: [PATCH 2/7] Variable filtering for single tau --- src/transferentropy/autoutils.jl | 38 +++++++++++++++++++------------- test/runtests.jl | 27 +++++++++++++++++++++++ 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/transferentropy/autoutils.jl b/src/transferentropy/autoutils.jl index e119ee5..b1a9a2e 100644 --- a/src/transferentropy/autoutils.jl +++ b/src/transferentropy/autoutils.jl @@ -24,7 +24,7 @@ removed from the """ function construct_candidate_variables(source, target, cond; k::Int = 1, - exclude::Union{Int, Nothing} = nothing, + τexclude::Union{Int, Nothing} = nothing, include_instantaneous = true, method_delay = "ac_min", maxlag::Union{Int, Float64} = 0.05) @@ -43,7 +43,7 @@ function construct_candidate_variables(source, target, cond; τsmax_source = [estimate_delay(s, method_delay, τs) for s in source] τsmax_target = [estimate_delay(t, method_delay, τs) for t in target] τsmax_cond = [estimate_delay(c, method_delay, τs) for c in cond] - + # Generate candidate set startlag = include_instantaneous ? 0 : -1 @@ -55,27 +55,29 @@ function construct_candidate_variables(source, target, cond; js_targetfuture = [i for i in length(τs_source)+1:length(τs_source)+length(τs_target)] τs = [τs_source..., τs_target..., τs_cond...] js = [[i for x in 1:length(τs[i])] for i = 1:length(τs)] - + + # Variable filtering, if desired + if τexclude isa Int + τs = [filtered_τs(τsᵢ, jsᵢ, τexclude) for (τsᵢ, jsᵢ) in zip(τs, js)] + js = [filtered_js(τsᵢ, jsᵢ, τexclude) for (τsᵢ, jsᵢ) in zip(τs, js)] + end return [τs..., ks_targetfuture], [js..., js_targetfuture] end -# Usaully, we use all lags from startlag:-\tau_max. These functions are used to exclude some lags -# in those ranges, if necessary. -exclude_lags(τs::AbstractVector{Int}, js::AbstractVector{Int}, exclude::Int) = - [τ for τ in τs if abs(τ) != abs.(exclude)] +# Usaully, we use all lags from startlag:-\tau_max to construct variables. In some situations, +# we may want to exclude som of those variables. +function filtered_τs(τs::AbstractVector{Int}, js::AbstractVector{Int}, τexclude::Int) + [τ for τ in τs if abs(τ) != abs.(τexclude)] +end -function exclude_lags(τs::AbstractVector{Int}, js::AbstractVector{Int}, exclude::AbstractVector{Int}) - if isempty(exclude) - return τs - else - return [τ for τ in τs if abs(x) ∉ abs.(exclude)] - end +function filtered_js(τs::AbstractVector{Int}, js::AbstractVector{Int}, τexclude::Int) + [j for (τ, j) in zip(τs, js) if abs(τ) != abs.(τexclude)] end -exclude_lags(τs::Vector{AbstractVector{Int}}, exclude) = [exclude_lags(l, exclude) for l in τs] # source & target variant function construct_candidate_variables(source, target; k::Int = 1, + τexclude::Union{Int, Nothing} = nothing, include_instantaneous = true, method_delay = "mi_min", maxlag::Union{Int, Float64} = 0.05) @@ -93,7 +95,7 @@ function construct_candidate_variables(source, target; # Find the maximum allowed embedding lag for each of the candidates. τsmax_source = [estimate_delay(s, method_delay, τs) for s in source] τsmax_target = [estimate_delay(t, method_delay, τs) for t in target] - + # Generate candidate set startlag = include_instantaneous ? 0 : -1 τs_source = [[startlag:-1:-τ...,] for τ in τsmax_source] @@ -103,6 +105,12 @@ function construct_candidate_variables(source, target; js_targetfuture = [i for i in length(τs_source)+1:length(τs_source)+length(τs_target)] τs = [τs_source..., τs_target...,] js = [[i for x in 1:length(τs[i])] for i = 1:length(τs)] + + # Variable filtering, if desired + if τexclude isa Int + τs = [filtered_τs(τsᵢ, jsᵢ, τexclude) for (τsᵢ, jsᵢ) in zip(τs, js)] + js = [filtered_js(τsᵢ, jsᵢ, τexclude) for (τsᵢ, jsᵢ) in zip(τs, js)] + end return [τs..., ks_targetfuture], [js..., js_targetfuture] end diff --git a/test/runtests.jl b/test/runtests.jl index 430b6ca..8c6182c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -54,6 +54,7 @@ end @testset "Transfer entropy" begin s, t, c = rand(100), rand(100), rand(100) + println("Starting transfer entropy tests...") @testset "Generalized Renyi transfer entropy" begin # Straight-forward estimators @@ -120,6 +121,32 @@ end end @testset "Automated estimators" begin + @testset "Variable exclusion" begin + # Use periodic signals, so we also can test variable selection methods, + # which for sensible testing, need to have their autocorrelation minima + # > 1. + s = sin.(1:100) .+ rand(100) + t = sin.(1:100) .+ rand(100) + c = sin.(1:100) .+ rand(100) + + τexclude = 1 + vars = TransferEntropy.construct_candidate_variables([s], [t], τexclude = nothing) + var_exclude = TransferEntropy.construct_candidate_variables([s], [t], τexclude = τexclude) + fvars = Iterators.flatten(vars[1][1:end-1]) |> collect + fvars_ex = Iterators.flatten(vars_ex[1][1:end-1]) |> collect + @test τexclude ∈ fvars + @test τexclude ∉ fvars + @test length(fvars) > length(fvars_ex) + + vars = TransferEntropy.construct_candidate_variables([s], [t], [c], τexclude = nothing) + var_exclude = TransferEntropy.construct_candidate_variables([s], [t], [c], τexclude = τexclude) + fvars = Iterators.flatten(vars[1][1:end-1]) |> collect + fvars_ex = Iterators.flatten(vars_ex[1][1:end-1]) |> collect + @test τexclude ∈ fvars + @test τexclude ∉ fvars + @test length(fvars) > length(fvars_ex) + end + est = VisitationFrequency(RectangularBinning(3)) te_st, params_st = bbnue(s, t, est) te_stc, params_stc = bbnue(s, t, c, est) From 20ec6f0e36c40ee8d2d550ec55def661660cd4de Mon Sep 17 00:00:00 2001 From: Kristian Haaga Date: Tue, 14 Dec 2021 11:42:22 +0100 Subject: [PATCH 3/7] Fix tests --- test/runtests.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 8c6182c..8d7a99b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -131,19 +131,19 @@ end τexclude = 1 vars = TransferEntropy.construct_candidate_variables([s], [t], τexclude = nothing) - var_exclude = TransferEntropy.construct_candidate_variables([s], [t], τexclude = τexclude) + vars_ex = TransferEntropy.construct_candidate_variables([s], [t], τexclude = τexclude) fvars = Iterators.flatten(vars[1][1:end-1]) |> collect fvars_ex = Iterators.flatten(vars_ex[1][1:end-1]) |> collect - @test τexclude ∈ fvars - @test τexclude ∉ fvars + @test τexclude ∈ abs.(fvars) + @test τexclude ∉ abs.(fvars_ex) @test length(fvars) > length(fvars_ex) vars = TransferEntropy.construct_candidate_variables([s], [t], [c], τexclude = nothing) - var_exclude = TransferEntropy.construct_candidate_variables([s], [t], [c], τexclude = τexclude) + vars_ex = TransferEntropy.construct_candidate_variables([s], [t], [c], τexclude = τexclude) fvars = Iterators.flatten(vars[1][1:end-1]) |> collect fvars_ex = Iterators.flatten(vars_ex[1][1:end-1]) |> collect - @test τexclude ∈ fvars - @test τexclude ∉ fvars + @test τexclude ∈ abs.(fvars) + @test τexclude ∉ abs.(fvars_ex) @test length(fvars) > length(fvars_ex) end From c703aa54d1daca6d925146a93b75f4fef711a6f4 Mon Sep 17 00:00:00 2001 From: Kristian Haaga Date: Tue, 14 Dec 2021 11:47:30 +0100 Subject: [PATCH 4/7] Internals changed, up minor version --- Project.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index e0ed653..6746d0b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,15 +1,19 @@ name = "TransferEntropy" uuid = "ea221983-52f3-5440-99c7-13ea201cd633" repo = "https://github.com/kahaaga/TransferEntropy.jl.git" -version = "1.4.0" +version = "1.5.0" [deps] DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2" DelayEmbeddings = "5732040d-69e3-5649-938a-b6b4f237613f" Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8" Entropies = "ed8fcbec-b94c-44b6-89df-898894ad9591" Neighborhood = "645ca80c-8b79-4109-87ea-e1f58159d116" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" +Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" From 25619ec668412a7805f9a9e3cd7e91a04c919f8a Mon Sep 17 00:00:00 2001 From: Kristian Haaga Date: Tue, 14 Dec 2021 11:47:50 +0100 Subject: [PATCH 5/7] Change wording in documentation --- src/transferentropy/autoutils.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transferentropy/autoutils.jl b/src/transferentropy/autoutils.jl index b1a9a2e..25cd286 100644 --- a/src/transferentropy/autoutils.jl +++ b/src/transferentropy/autoutils.jl @@ -20,7 +20,7 @@ If `maxlag` is an integer, `maxlag` is taken as the maximum allowed embedding la then the maximum embedding lag is taken as `maximum([length.(source); length.(target); length.(cond)])*maxlag`. If `exclude` is an integer, all variables whose embedding lag has absolute value equal to `exclude` will be -removed from the +excluded. """ function construct_candidate_variables(source, target, cond; k::Int = 1, @@ -43,7 +43,7 @@ function construct_candidate_variables(source, target, cond; τsmax_source = [estimate_delay(s, method_delay, τs) for s in source] τsmax_target = [estimate_delay(t, method_delay, τs) for t in target] τsmax_cond = [estimate_delay(c, method_delay, τs) for c in cond] - + # Generate candidate set startlag = include_instantaneous ? 0 : -1 @@ -79,7 +79,7 @@ function construct_candidate_variables(source, target; k::Int = 1, τexclude::Union{Int, Nothing} = nothing, include_instantaneous = true, - method_delay = "mi_min", + method_delay = "ac_min", maxlag::Union{Int, Float64} = 0.05) # Ensure all time series are of the same length. From a44180b023904467e864ec055a8557d13fcd3611 Mon Sep 17 00:00:00 2001 From: Kristian Haaga Date: Tue, 14 Dec 2021 11:51:58 +0100 Subject: [PATCH 6/7] Remove packages from deps --- Project.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Project.toml b/Project.toml index 6746d0b..84cd9d4 100644 --- a/Project.toml +++ b/Project.toml @@ -7,13 +7,9 @@ version = "1.5.0" DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2" DelayEmbeddings = "5732040d-69e3-5649-938a-b6b4f237613f" Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8" Entropies = "ed8fcbec-b94c-44b6-89df-898894ad9591" Neighborhood = "645ca80c-8b79-4109-87ea-e1f58159d116" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" -Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" From eae0a86a009b9b8c88374f2a73c45609f5a16593 Mon Sep 17 00:00:00 2001 From: Kristian Haaga Date: Tue, 14 Dec 2021 11:53:05 +0100 Subject: [PATCH 7/7] Update docs --- src/transferentropy/autoutils.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/transferentropy/autoutils.jl b/src/transferentropy/autoutils.jl index 25cd286..262dd3f 100644 --- a/src/transferentropy/autoutils.jl +++ b/src/transferentropy/autoutils.jl @@ -4,8 +4,9 @@ using DelayEmbeddings, Statistics construct_candidate_variables( source::Vector{AbstractVector}, target::Vector{AbstractVector}, - cond::Vector{AbstractVector}; + [cond::Vector{AbstractVector}]; k::Int = 1, include_instantaneous = true, + τexclude::Union{Int, Nothing} = nothing, maxlag::Union{Int, Float64} = 0.05 ) → ([τs_source, τs_target, τs_cond, ks_targetfuture], [js_source, js_target, js_cond, js_targetfuture]) @@ -19,7 +20,7 @@ the variables. If `maxlag` is an integer, `maxlag` is taken as the maximum allowed embedding lag. If `maxlag` is a float, then the maximum embedding lag is taken as `maximum([length.(source); length.(target); length.(cond)])*maxlag`. -If `exclude` is an integer, all variables whose embedding lag has absolute value equal to `exclude` will be +If `τexclude` is an integer, all variables whose embedding lag has absolute value equal to `exclude` will be excluded. """ function construct_candidate_variables(source, target, cond;