Skip to content

Commit 42946f4

Browse files
committed
more updatres to AR appraoc
1 parent 05d63c2 commit 42946f4

File tree

3 files changed

+49
-46
lines changed

3 files changed

+49
-46
lines changed

EpiAware/src/EpiLatentModels/models/HierarchicalNormal.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ The `HierarchicalNormal` struct represents a non-centered hierarchical normal di
55
66
- `HierarchicalNormal(mean, std_prior)`: Constructs a `HierarchicalNormal` instance with the specified mean and standard deviation prior.
77
- `HierarchicalNormal(; mean = 0.0, std_prior = truncated(Normal(0,1), 0, Inf))`: Constructs a `HierarchicalNormal` instance with the specified mean and standard deviation prior using named arguments and with default values.
8-
8+
- `HierarchicalNormal(std_prior)`: Constructs a `HierarchicalNormal` instance with the specified standard deviation prior.
99
## Examples
1010
1111
```jldoctest HierarchicalNormal
@@ -29,6 +29,10 @@ rand(mdl)
2929
@kwdef struct HierarchicalNormal{R <: Real, D <: Sampleable} <: AbstractTuringLatentModel
3030
mean::R = 0.0
3131
std_prior::D = truncated(Normal(0, 1), 0, Inf)
32+
33+
function HierarchicalNormal(std_prior::D)
34+
return HierarchicalNormal(; mean = 0.0, std_prior = std_prior)
35+
end
3236
end
3337

3438
@doc raw"

EpiAware/src/EpiLatentModels/models/MA.jl

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
The moving average (MA) model struct.
33
44
# Constructors
5-
- `MA(coef_prior::Distribution, std_prior::Distribution; q::Int = 1, ϵ_t::AbstractTuringLatentModel = IDD(Normal()))`: Constructs an MA model with the specified prior distributions for MA coefficients and standard deviation. The order of the MA model and the error term distribution can also be specified.
5+
- `MA(θ::Distribution, σ::Distribution; q::Int = 1, ϵ::AbstractTuringLatentModel = IDD(Normal()))`: Constructs an MA model with the specified prior distributions.
66
7-
- `MA(; coef_priors::Vector{C} = [truncated(Normal(0.0, 0.05), -1, 1)], std_prior::Distribution = HalfNormal(0.1), ϵ_t::AbstractTuringLatentModel = IDD(Normal())) where {C <: Distribution}`: Constructs an MA model with the specified prior distributions for MA coefficients, standard deviation, and error term. The order of the MA model is determined by the length of the `coef_priors` vector.
7+
- `MA(; θ::Vector{C} = [truncated(Normal(0.0, 0.05), -1, 1)], σ::Distribution = HalfNormal(0.1), ϵ::AbstractTuringLatentModel = HierarchicalNormal) where {C <: Distribution}`: Constructs an MA model with the specified prior distributions.
88
9-
- `MA(coef_prior::Distribution, std_prior::Distribution, q::Int, ϵ_t::AbstractTuringLatentModel)`: Constructs an MA model with the specified prior distributions for MA coefficients, standard deviation, and error term. The order of the MA model is explicitly specified.
9+
- `MA(θ::Distribution, q::Int, ϵ_t::AbstractTuringLatentModel)`: Constructs an MA model with the specified prior distributions and order.
10+
11+
# Parameters
12+
- `θ`: Prior distribution for the MA coefficients. For MA(q), this should be a vector of q distributions or a multivariate distribution of dimension q.
13+
- `q`: Order of the MA model, i.e., the number of lagged error terms.
14+
- `ϵ_t`: Distribution of the error term, typically standard normal.
1015
1116
# Examples
1217
@@ -32,35 +37,32 @@ rand(mdl)
3237

3338
struct MA{C <: Sampleable, S <: Sampleable, Q <: Int, E <: AbstractTuringLatentModel} <:
3439
AbstractTuringLatentModel
35-
"Prior distribution for the MA coefficients."
36-
coef_prior::C
37-
"Prior distribution for the standard deviation."
38-
std_prior::S
39-
"Order of the MA model."
40+
"Prior distribution for the MA coefficients. For MA(q), this should be a vector of q distributions or a multivariate distribution of dimension q"
41+
θ::C
42+
"Order of the MA model, i.e., the number of lagged error terms."
4043
q::Q
4144
"Prior distribution for the error term."
4245
ϵ_t::E
4346

44-
function MA(coef_prior::Distribution, std_prior::Distribution;
45-
q::Int = 1, ϵ_t::AbstractTuringLatentModel = IDD(Normal()))
46-
coef_priors = fill(coef_prior, q)
47-
return MA(; coef_priors = coef_priors, std_prior = std_prior, ϵ_t = ϵ_t)
47+
function MA(θ::Distribution, σ::Distribution;
48+
q::Int = 1, ϵ::AbstractTuringLatentModel = IDD(Normal()))
49+
θ_priors = fill(θ, q)
50+
return MA(; θ_priors = θ_priors, σ = σ, ϵ = ϵ)
4851
end
4952

50-
function MA(; coef_priors::Vector{C} = [truncated(Normal(0.0, 0.05), -1, 1)],
51-
std_prior::Distribution = HalfNormal(0.1),
52-
ϵ_t::AbstractTuringLatentModel = IDD(Normal())) where {C <: Distribution}
53-
q = length(coef_priors)
54-
coef_prior = _expand_dist(coef_priors)
55-
return MA(coef_prior, std_prior, q, ϵ_t)
53+
function MA(; θ_priors::Vector{C} = [truncated(Normal(0.0, 0.05), -1, 1)],
54+
σ::Distribution = HalfNormal(0.1),
55+
ϵ::AbstractTuringLatentModel = IDD(Normal())) where {C <: Distribution}
56+
q = length(θ_priors)
57+
θ = _expand_dist(θ_priors)
58+
return MA(θ, q, ϵ)
5659
end
5760

58-
function MA(coef_prior::Distribution, std_prior::Distribution,
59-
q::Int, ϵ_t::AbstractTuringLatentModel)
61+
function MA::Distribution, q::Int, ϵ::AbstractTuringLatentModel)
6062
@assert q>0 "q must be greater than 0"
61-
@assert q==length(coef_prior) "q must be equal to the length of coef_prior"
62-
new{typeof(coef_prior), typeof(std_prior), typeof(q), typeof(ϵ_t)}(
63-
coef_prior, std_prior, q, ϵ_t
63+
@assert q==length(θ) "q must be equal to the length of θ"
64+
new{typeof(θ), typeof(σ), typeof(q), typeof(ϵ)}(
65+
θ, q, ϵ
6466
)
6567
end
6668
end
@@ -82,15 +84,12 @@ Generate a latent MA series.
8284
@model function EpiAwareBase.generate_latent(latent_model::MA, n)
8385
q = latent_model.q
8486
@assert n>q "n must be longer than order of the moving average process"
85-
86-
σ ~ latent_model.std_prior
87-
coef_MA ~ latent_model.coef_prior
88-
@submodel ϵ_t = generate_latent(latent_model.ϵ_t, n)
89-
scaled_ϵ_t = σ_MA * ϵ_t
87+
θ ~ latent_model.θ
88+
@submodel ϵ_t = generate_latent(latent_model.ϵ, n)
9089

9190
ma = accumulate_scan(
92-
MAStep(coef_MA),
93-
(; val = 0, state = scaled_ϵ_t[1:q]), scaled_ϵ_t[(q + 1):end])
91+
MAStep(θ),
92+
(; val = 0, state = ϵ_t[1:q]), ϵ_t[(q + 1):end])
9493

9594
return ma
9695
end
@@ -99,14 +98,14 @@ end
9998
The moving average (MA) step function struct
10099
"
101100
struct MAStep{C <: AbstractVector{<:Real}} <: AbstractAccumulationStep
102-
coef_MA::C
101+
θ::C
103102
end
104103

105104
@doc raw"
106105
The moving average (MA) step function for use with `accumulate_scan`.
107106
"
108107
function (ma::MAStep)(state, ϵ)
109-
new_val = ϵ + dot(ma.coef_MA, state.state)
108+
new_val = ϵ + dot(ma.θ, state.state)
110109
new_state = vcat(ϵ, state.state[1:(end - 1)])
111110
return (; val = new_val, state = new_state)
112111
end

EpiAware/test/EpiLatentModels/models/MA.jl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
@testitem "Testing MA constructor" begin
22
using Distributions, Turing
33

4-
coef_prior = truncated(Normal(0.0, 0.05), -1, 1)
5-
std_prior = HalfNormal(0.1)
6-
ma_process = MA(coef_prior, std_prior)
4+
θ_prior = truncated(Normal(0.0, 0.05), -1, 1)
5+
σ_prior = HalfNormal(0.1)
6+
ma_process = MA(θ_prior, σ_prior)
77

8-
@test ma_process.coef_prior == filldist(coef_prior, 1)
9-
@test ma_process.std_prior == std_prior
8+
@test ma_process.θ_prior == filldist(θ_prior, 1)
9+
@test ma_process.σ_prior == σ_prior
1010
@test ma_process.q == 1
1111
@test ma_process.ϵ_t isa IDD
1212
end
1313

1414
@testitem "Test MA(2)" begin
1515
using Distributions, Turing
16-
coef_prior = truncated(Normal(0.0, 0.05), -1, 1)
16+
θ_prior = truncated(Normal(0.0, 0.05), -1, 1)
1717
ma = MA(
18-
coef_priors = [coef_prior, coef_prior],
19-
std_prior = HalfNormal(0.1)
18+
θ_priors = [θ_prior, θ_prior],
19+
σ_prior = HalfNormal(0.1)
2020
)
2121
@test ma.q == 2
2222
@test ma.ϵ_t isa IDD
23-
@test ma.coef_prior == filldist(coef_prior, 2)
23+
@test ma.θ_prior == filldist(θ_prior, 2)
2424
end
2525

2626
@testitem "Testing MA process against theoretical properties" begin
@@ -30,11 +30,11 @@ end
3030

3131
ma_model = MA()
3232
n = 1000
33-
coef_MA = [0.1]
34-
σ_MA = 1.0
33+
θ = [0.1]
34+
σ = 1.0
3535

3636
model = generate_latent(ma_model, n)
37-
fixed_model = fix(model, (σ_MA = σ_MA, coef_MA = coef_MA))
37+
fixed_model = fix(model, (σ = σ, θ = θ))
3838

3939
n_samples = 100
4040
samples = sample(fixed_model, Prior(), n_samples; progress = false) |>
@@ -43,7 +43,7 @@ end
4343
end
4444

4545
theoretical_mean = 0.0
46-
theoretical_var = σ_MA^2 * (1 + sum(coef_MA .^ 2))
46+
theoretical_var = σ^2 * (1 + sum(θ .^ 2))
4747

4848
@test isapprox(mean(samples), theoretical_mean, atol = 0.1)
4949
@test isapprox(var(samples), theoretical_var, atol = 0.2)

0 commit comments

Comments
 (0)