From 4e5fe4231710e28d17e4de5160aeaf0434131738 Mon Sep 17 00:00:00 2001 From: Samuel Brand Date: Wed, 28 Aug 2024 10:24:04 +0100 Subject: [PATCH 1/5] reverse damp parameters --- EpiAware/src/EpiLatentModels/models/AR.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/EpiAware/src/EpiLatentModels/models/AR.jl b/EpiAware/src/EpiLatentModels/models/AR.jl index ad17556d9..1b02759bc 100644 --- a/EpiAware/src/EpiLatentModels/models/AR.jl +++ b/EpiAware/src/EpiLatentModels/models/AR.jl @@ -81,23 +81,26 @@ Generate a latent AR series. damp_AR ~ latent_model.damp_prior ϵ_t ~ filldist(Normal(), n - p) - ar = accumulate_scan(ARStep(damp_AR), ar_init, σ_AR * ϵ_t) + ar_step = ARStep(reverse(damp_AR)) + ar = accumulate_scan(ar_step, ar_init, σ_AR * ϵ_t) return ar end @doc raw" -The autoregressive (AR) step function struct +The autoregressive (AR) step function struct. + +Note that the AR parameters are stored in reverse order. " struct ARStep{D <: AbstractVector{<:Real}} <: AbstractAccumulationStep - damp_AR::D + rev_damp_AR::D end @doc raw" The autoregressive (AR) step function for use with `accumulate_scan`. " function (ar::ARStep)(state, ϵ) - new_val = dot(ar.damp_AR, state) + ϵ + new_val = dot(ar.rev_damp_AR, state) + ϵ new_state = vcat(state[2:end], new_val) return new_state end From 2b1411fc03c2f1166d6aa2d3061ce27a06fae965 Mon Sep 17 00:00:00 2001 From: Samuel Brand <48288458+SamuelBrand1@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:04:03 +0100 Subject: [PATCH 2/5] Add a theoretical test for AR(2) --- EpiAware/test/EpiLatentModels/models/AR.jl | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/EpiAware/test/EpiLatentModels/models/AR.jl b/EpiAware/test/EpiLatentModels/models/AR.jl index 0e99b7b25..e5a511183 100644 --- a/EpiAware/test/EpiLatentModels/models/AR.jl +++ b/EpiAware/test/EpiLatentModels/models/AR.jl @@ -58,7 +58,7 @@ end end end -@testitem "Testing AR process against theoretical properties" begin +@testitem "Testing AR(1) process against theoretical properties" begin using DynamicPPL, Turing using HypothesisTests: ExactOneSampleKSTest, pvalue using Distributions @@ -88,3 +88,32 @@ end samples, Normal(theoretical_mean, sqrt(theoretical_var))) |> pvalue @test ks_test_pval > 1e-6 end + +@testitem "Testing AR(2) process against theoretical properties" begin + using DynamicPPL, Turing + using HypothesisTests: ExactOneSampleKSTest, pvalue + using Distributions + + ar_model = AR(Normal(), HalfNormal(0.1), Normal(), p = 2) + n = 10_000 + damp = [0.8, 0.1] + σ_AR = 1.0 + + theoretical_mean = 0.0 + theoretical_var = σ_AR^2 / (1 - damp[1]^2 - damp[2]^2 - + 2 * (damp[1]^2 * damp[2] / (1 - damp[2]))) + theoretical_1step_cov = theoretical_var * damp[1] / (1 - damp[2]) + init_Σ = [theoretical_var theoretical_1step_cov; theoretical_1step_cov theoretical_var] + + # Draw initial values from the stationary distribution so process starts at stationarity + ar_init = rand(MvNormal(zeros(2), init_Σ)) + + model = generate_latent(ar_model, n) + fixed_model = fix(model, (σ_AR = σ_AR, damp_AR = damp, ar_init = ar_init)) + # Draw samples from the model + X = fixed_model() + + ks_test_pval = ExactOneSampleKSTest( + X, Normal(theoretical_mean, sqrt(theoretical_var))) |> pvalue + @test ks_test_pval > 1e-6 +end From dfd9f6ecd5b3e3ef3eb01abc616e2125e48e6e71 Mon Sep 17 00:00:00 2001 From: Samuel Brand <48288458+SamuelBrand1@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:37:14 +0100 Subject: [PATCH 3/5] Add rev_damp_prior field to AR --- EpiAware/src/EpiLatentModels/models/AR.jl | 18 ++++++++++-------- EpiAware/test/EpiLatentModels/models/AR.jl | 5 +++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/EpiAware/src/EpiLatentModels/models/AR.jl b/EpiAware/src/EpiLatentModels/models/AR.jl index 1b02759bc..ac6a1217a 100644 --- a/EpiAware/src/EpiLatentModels/models/AR.jl +++ b/EpiAware/src/EpiLatentModels/models/AR.jl @@ -28,6 +28,8 @@ struct AR{D <: Sampleable, S <: Sampleable, I <: Sampleable, P <: Int} <: init_prior::I "Order of the AR model." p::P + "Reversed order of the damping coefficients for computation." + rev_damp_prior::D function AR(damp_prior::Distribution, std_prior::Distribution, init_prior::Distribution; p::Int = 1) damp_priors = fill(damp_prior, p) @@ -43,17 +45,18 @@ struct AR{D <: Sampleable, S <: Sampleable, I <: Sampleable, P <: Int} <: p = length(damp_priors) damp_prior = _expand_dist(damp_priors) init_prior = _expand_dist(init_priors) - return AR(damp_prior, std_prior, init_prior, p) + rev_damp_prior = _expand_dist(reverse(damp_priors)) + return AR(damp_prior, std_prior, init_prior, p, rev_damp_prior) end function AR(damp_prior::Distribution, std_prior::Distribution, - init_prior::Distribution, p::Int) + init_prior::Distribution, p::Int, rev_damp_prior::Distribution) @assert p>0 "p must be greater than 0" @assert length(damp_prior)==length(init_prior) "damp_prior and init_prior must have the same length" @assert p==length(damp_prior) "p must be equal to the length of damp_prior" - new{typeof(damp_prior), typeof(std_prior), typeof(init_prior), typeof(p)}( - damp_prior, std_prior, init_prior, p - ) + new{typeof(damp_prior), typeof(std_prior), + typeof(init_prior), typeof(p)}( + damp_prior, std_prior, init_prior, p, rev_damp_prior) end end @@ -78,11 +81,10 @@ Generate a latent AR series. σ_AR ~ latent_model.std_prior ar_init ~ latent_model.init_prior - damp_AR ~ latent_model.damp_prior + rev_damp_AR ~ latent_model.rev_damp_prior ϵ_t ~ filldist(Normal(), n - p) - ar_step = ARStep(reverse(damp_AR)) - ar = accumulate_scan(ar_step, ar_init, σ_AR * ϵ_t) + ar = accumulate_scan(ARStep(rev_damp_AR), ar_init, σ_AR * ϵ_t) return ar end diff --git a/EpiAware/test/EpiLatentModels/models/AR.jl b/EpiAware/test/EpiLatentModels/models/AR.jl index e5a511183..5276bc92a 100644 --- a/EpiAware/test/EpiLatentModels/models/AR.jl +++ b/EpiAware/test/EpiLatentModels/models/AR.jl @@ -92,7 +92,8 @@ end @testitem "Testing AR(2) process against theoretical properties" begin using DynamicPPL, Turing using HypothesisTests: ExactOneSampleKSTest, pvalue - using Distributions + using Distributions, Random + Random.seed!(1234) ar_model = AR(Normal(), HalfNormal(0.1), Normal(), p = 2) n = 10_000 @@ -109,7 +110,7 @@ end ar_init = rand(MvNormal(zeros(2), init_Σ)) model = generate_latent(ar_model, n) - fixed_model = fix(model, (σ_AR = σ_AR, damp_AR = damp, ar_init = ar_init)) + fixed_model = fix(model, (σ_AR = σ_AR, rev_damp_AR = reverse(damp), ar_init = ar_init)) # Draw samples from the model X = fixed_model() From ba8a4b37321d06f01eef68d3a084d606c35154ab Mon Sep 17 00:00:00 2001 From: Samuel Brand <48288458+SamuelBrand1@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:42:35 +0100 Subject: [PATCH 4/5] Update AR.jl --- EpiAware/test/EpiLatentModels/models/AR.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EpiAware/test/EpiLatentModels/models/AR.jl b/EpiAware/test/EpiLatentModels/models/AR.jl index 5276bc92a..4ad6244f2 100644 --- a/EpiAware/test/EpiLatentModels/models/AR.jl +++ b/EpiAware/test/EpiLatentModels/models/AR.jl @@ -96,7 +96,7 @@ end Random.seed!(1234) ar_model = AR(Normal(), HalfNormal(0.1), Normal(), p = 2) - n = 10_000 + n = 1000 damp = [0.8, 0.1] σ_AR = 1.0 From 4d6513b403834377387f29c47082f69bab10b687 Mon Sep 17 00:00:00 2001 From: Samuel Brand <48288458+SamuelBrand1@users.noreply.github.com> Date: Wed, 28 Aug 2024 12:05:52 +0100 Subject: [PATCH 5/5] fix plot with change in sampled quanitity from AR --- .../docs/src/showcase/replications/mishra-2020/index.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/EpiAware/docs/src/showcase/replications/mishra-2020/index.jl b/EpiAware/docs/src/showcase/replications/mishra-2020/index.jl index 553a3973a..d8787fdf0 100644 --- a/EpiAware/docs/src/showcase/replications/mishra-2020/index.jl +++ b/EpiAware/docs/src/showcase/replications/mishra-2020/index.jl @@ -1,5 +1,5 @@ ### A Pluto.jl notebook ### -# v0.19.43 +# v0.19.46 using Markdown using InteractiveUtils @@ -545,7 +545,7 @@ let c = :black, lab = "prior") - p3 = histogram(inference_results.samples["latent.damp_AR[1]"], + p3 = histogram(inference_results.samples["latent.rev_damp_AR[2]"], lab = "chain " .* string.([1 2 3 4]), fillalpha = 0.4, lw = 0, @@ -556,7 +556,7 @@ let c = :black, lab = "prior") - p4 = histogram(inference_results.samples["latent.damp_AR[2]"], + p4 = histogram(inference_results.samples["latent.rev_damp_AR[1]"], lab = "chain " .* string.([1 2 3 4]), fillalpha = 0.4, lw = 0,