-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue 408: ARMA and ARIMA models (#438)
* draft MA method * draft MA methd * use IDD for epsilon in all models * add MA benchmark * Add docs and tests for IDD * make episilon_t a arg of the latent model constructors * improve MA correctness * fully import EpiAwareUtils * add a test for IDD * add tests for MA.jl * add doc tests and unit tests + start on helper fn * more updatres to AR appraoc * chase down partial arg changes * clean up AR * clean up and add arma and arima helpers * Contributions towards Arma/Arima models (#531) * Patch: Switch to fork of benchmarkCI (#520) * patch to fork of benchmarkCI * put fork version of BenchmarkCI in [sources] * swap order * add EpiAware [source] * fix path * rm benchmarkCI from project * Patch fix: add `Manifest.toml` to benchmarking (#524) * trigger * Update benchmark.yaml * Update benchmark.yaml * commit benchmark Manifest * try alternate approach * Update benchmark.yaml * Update EpiMethod.jl * Update benchmark.yaml * change baseline to origin/main * remove trigger * rm other trigger * Issue 465: Add an infection generating model for ODE problems (#510) * CompatHelper: bump compat for Turing to 0.35 for package EpiAware, (drop existing compat) (#516) * CompatHelper: bump compat for Turing to 0.35 for package EpiAware, (drop existing compat) * Update Project.toml * fix Project.toml --------- Co-authored-by: CompatHelper Julia <compathelper_noreply@julialang.org> Co-authored-by: Sam Abbott <azw1@cdc.gov> Co-authored-by: Samuel Brand <48288458+SamuelBrand1@users.noreply.github.com> Co-authored-by: Samuel Brand <sam055@mac.com> * CompatHelper: bump compat for DynamicPPL to 0.30 for package EpiAware, (drop existing compat) (#528) Co-authored-by: CompatHelper Julia <compathelper_noreply@julialang.org> * rename IDD -> IID * rename test file * Issue 529: Create null Latent model (#530) * Null Latent model * Null Latent model * fix doctest * fix generate_epiaware unit tests New usage of RW * fix turing method test underlying std of step size changed name * fix broadcast test Underlying std param changed name * fix HN unit test Default std prior had changed * fix AR unit tests --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: CompatHelper Julia <compathelper_noreply@julialang.org> Co-authored-by: Sam Abbott <azw1@cdc.gov> * revert define_ namming * clean out repeated utils from merge * fix MA tests * fix RW tests - feel made about RandomWalk vs AR naming * fix remaining unit tests that aren't doctests * update latent recovery test * try and fix doctests automatically * update all doctests to output nothing - this is awful * add doctests for arima and arma * fix doctest * clean up deps * update replication studies * add interface tests for combination functions and add benchmarks * add some basic theoretical properties tests * name change IDD -> IID benchmarks * moving all the constructors because this PR is too contained * catch missing using * update iid benchmark: * update extraction * remove old param namme from case study * get the dot * get the dot * fix initial guess point for MAP opt * Update index.jl * add a compile time branch for HN * add a compile time branch for HN * update test * add a new constructor to get old default behaviour * update docs * update docs - using the structs for priors is very brittle * reorder prior plots --------- Co-authored-by: Samuel Brand <48288458+SamuelBrand1@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: CompatHelper Julia <compathelper_noreply@julialang.org> Co-authored-by: Samuel Brand <sam055@mac.com>
1 parent
8dc444f
commit d7b7b3b
Showing
42 changed files
with
977 additions
and
318 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
@doc raw""" | ||
Define an ARIMA model by wrapping `define_arma` and applying differencing via `DiffLatentModel`. | ||
# Arguments | ||
- `ar_init`: Prior distribution for AR initial conditions. | ||
A vector of distributions. | ||
- `diff_init`: Prior distribution for differencing initial conditions. | ||
A vector of distributions. | ||
- `θ`: Prior distribution for MA coefficients. | ||
A vector of distributions. | ||
- `damp`: Prior distribution for AR damping coefficients. | ||
A vector of distributions. | ||
- `ϵ_t`: Distribution of the error term. | ||
Default is `HierarchicalNormal()`. | ||
# Returns | ||
An ARIMA model consisting of AR and MA components with differencing applied. | ||
# Example | ||
```jldoctest ARIMA; output = false | ||
using EpiAware, Distributions | ||
ARIMA = arima() | ||
arima_model = generate_latent(ARIMA, 10) | ||
arima_model() | ||
nothing | ||
# output | ||
``` | ||
""" | ||
function arima(; | ||
ar_init = [Normal()], | ||
diff_init = [Normal()], | ||
damp = [truncated(Normal(0.0, 0.05), 0, 1)], | ||
θ = [truncated(Normal(0.0, 0.05), -1, 1)], | ||
ϵ_t = HierarchicalNormal() | ||
) | ||
arma_model = arma(; init = ar_init, damp = damp, θ = θ, ϵ_t = ϵ_t) | ||
arima_model = DiffLatentModel(; model = arma_model, init_priors = diff_init) | ||
return arima_model | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
@doc raw""" | ||
Define an ARMA model using AR and MA components. | ||
# Arguments | ||
- `init`: Prior distribution for AR initial conditions. | ||
A vector of distributions. | ||
- `θ`: Prior distribution for MA coefficients. | ||
A vector of distributions. | ||
- `damp`: Prior distribution for AR damping coefficients. | ||
A vector of distributions. | ||
- `ϵ_t`: Distribution of the error term. | ||
Default is `HierarchicalNormal()`. | ||
# Returns | ||
An AR model with an MA model as its error term, effectively creating an ARMA model. | ||
# Example | ||
```jldoctest ARMA; output = false | ||
using EpiAware, Distributions | ||
ARMA = arma(; | ||
θ = [truncated(Normal(0.0, 0.02), -1, 1)], | ||
damp = [truncated(Normal(0.0, 0.02), 0, 1)] | ||
) | ||
arma_model = generate_latent(ARMA, 10) | ||
arma_model() | ||
nothing | ||
# output | ||
``` | ||
""" | ||
function arma(; | ||
init = [Normal()], | ||
damp = [truncated(Normal(0.0, 0.05), 0, 1)], | ||
θ = [truncated(Normal(0.0, 0.05), -1, 1)], | ||
ϵ_t = HierarchicalNormal()) | ||
ma = MA(; θ_priors = θ, ϵ_t = ϵ_t) | ||
ar = AR(; damp_priors = damp, init_priors = init, ϵ_t = ma) | ||
return ar | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
@doc raw" | ||
Model latent process ``\epsilon_t`` as independent and identically distributed random variables. | ||
## Mathematical specification | ||
The IID process ``\epsilon_t`` is specified as a sequence of independent and identically distributed random variables, | ||
```math | ||
\epsilon_t \sim \text{Prior}, \quad t = 1, 2, \ldots | ||
``` | ||
where Prior is the specified distribution. | ||
## Constructors | ||
- `IID(prior::Distribution = Normal(0, 1))`: Create an IID model with the specified prior distribution. | ||
## Examples | ||
```jldoctest IID; filter = r\"\b\d+(\.\d+)?\b\" => \"*\" | ||
using EpiAware, Distributions | ||
model = IID(Normal(0, 1)) | ||
# output | ||
IID{Normal{Float64}}(Distributions.Normal{Float64}(μ=0.0, σ=1.0)) | ||
``` | ||
```jldoctest IID; output = false | ||
idd = generate_latent(model, 10) | ||
idd() | ||
nothing | ||
# output | ||
``` | ||
" | ||
@kwdef struct IID{D <: Sampleable} <: AbstractTuringLatentModel | ||
ϵ_t::D = Normal(0, 1) | ||
end | ||
|
||
@doc raw" | ||
Generate latent variables from the IID (Independent and Identically Distributed) model. | ||
# Arguments | ||
- `model::IID`: The IID model. | ||
- `n`: Number of latent variables to generate. | ||
# Returns | ||
- `ϵ_t`: Generated latent variables. | ||
" | ||
@model function EpiAwareBase.generate_latent(model::IID, n) | ||
ϵ_t ~ filldist(model.ϵ_t, n) | ||
return ϵ_t | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
@doc raw" | ||
The moving average (MA) model struct. | ||
# Constructors | ||
- `MA(θ::Distribution, σ::Distribution; q::Int = 1, ϵ::AbstractTuringLatentModel = IID(Normal()))`: Constructs an MA model with the specified prior distributions. | ||
- `MA(; θ::Vector{C} = [truncated(Normal(0.0, 0.05), -1, 1)], ϵ::AbstractTuringLatentModel = HierarchicalNormal) where {C <: Distribution}`: Constructs an MA model with the specified prior distributions. | ||
- `MA(θ::Distribution, q::Int, ϵ_t::AbstractTuringLatentModel)`: Constructs an MA model with the specified prior distributions and order. | ||
# Parameters | ||
- `θ`: Prior distribution for the MA coefficients. For MA(q), this should be a vector of q distributions or a multivariate distribution of dimension q. | ||
- `q`: Order of the MA model, i.e., the number of lagged error terms. | ||
- `ϵ_t`: Distribution of the error term, typically standard normal. Defaults to `IID(Normal())`. | ||
# Examples | ||
```jldoctest MA; output = false | ||
using Distributions, Turing, EpiAware | ||
ma = MA() | ||
ma | ||
nothing | ||
# output | ||
``` | ||
```jldoctest MA; output = false | ||
mdl = generate_latent(ma, 10) | ||
mdl() | ||
nothing | ||
# output | ||
``` | ||
```jldoctest MA; output = false | ||
rand(mdl) | ||
nothing | ||
# output | ||
``` | ||
" | ||
|
||
struct MA{C <: Sampleable, Q <: Int, E <: AbstractTuringLatentModel} <: | ||
AbstractTuringLatentModel | ||
"Prior distribution for the MA coefficients. For MA(q), this should be a vector of q distributions or a multivariate distribution of dimension q" | ||
θ::C | ||
"Order of the MA model, i.e., the number of lagged error terms." | ||
q::Q | ||
"Prior distribution for the error term." | ||
ϵ_t::E | ||
|
||
function MA(θ::Distribution, q::Int, ϵ_t::AbstractTuringLatentModel) | ||
@assert q>0 "q must be greater than 0" | ||
@assert q==length(θ) "q must be equal to the length of θ" | ||
new{typeof(θ), typeof(q), typeof(ϵ_t)}(θ, q, ϵ_t) | ||
end | ||
end | ||
|
||
function MA(θ::Distribution; | ||
q::Int = 1, ϵ_t::AbstractTuringLatentModel = HierarchicalNormal()) | ||
θ_priors = fill(θ, q) | ||
return MA(; θ_priors = θ_priors, ϵ_t = ϵ_t) | ||
end | ||
|
||
function MA(; θ_priors::Vector{C} = [truncated(Normal(0.0, 0.05), -1, 1)], | ||
ϵ_t::AbstractTuringLatentModel = HierarchicalNormal()) where {C <: | ||
Distribution} | ||
q = length(θ_priors) | ||
θ = _expand_dist(θ_priors) | ||
return MA(θ, q, ϵ_t) | ||
end | ||
|
||
@doc raw" | ||
Generate a latent MA series. | ||
# Arguments | ||
- `latent_model::MA`: The MA model. | ||
- `n::Int`: The length of the MA series. | ||
# Returns | ||
- `ma::Vector{Float64}`: The generated MA series. | ||
# Notes | ||
- `n` must be longer than the order of the moving average process. | ||
" | ||
@model function EpiAwareBase.generate_latent(latent_model::MA, n) | ||
q = latent_model.q | ||
@assert n>q "n must be longer than order of the moving average process" | ||
θ ~ latent_model.θ | ||
@submodel ϵ_t = generate_latent(latent_model.ϵ_t, n) | ||
|
||
ma = accumulate_scan( | ||
MAStep(θ), | ||
(; val = 0, state = ϵ_t[1:q]), ϵ_t[(q + 1):end]) | ||
|
||
return ma | ||
end | ||
|
||
@doc raw" | ||
The moving average (MA) step function struct | ||
" | ||
struct MAStep{C <: AbstractVector{<:Real}} <: AbstractAccumulationStep | ||
θ::C | ||
end | ||
|
||
@doc raw" | ||
The moving average (MA) step function for use with `accumulate_scan`. | ||
" | ||
function (ma::MAStep)(state, ϵ) | ||
new_val = ϵ + dot(ma.θ, state.state) | ||
new_state = vcat(ϵ, state.state[1:(end - 1)]) | ||
return (; val = new_val, state = new_state) | ||
end | ||
|
||
@doc raw" | ||
The MA step function method for get_state. | ||
" | ||
function EpiAwareUtils.get_state(acc_step::MAStep, initial_state, state) | ||
init_vals = initial_state.state | ||
new_vals = state .|> x -> x.val | ||
return vcat(init_vals, new_vals) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
@testitem "Testing ARIMA constructor" begin | ||
using Distributions, Turing | ||
|
||
# Test default constructor | ||
arima_model = arima() | ||
@test arima_model isa DiffLatentModel | ||
@test arima_model.model isa AR | ||
@test arima_model.model.ϵ_t isa MA | ||
@test length(arima_model.model.damp_prior) == 1 | ||
@test length(arima_model.model.init_prior) == 1 | ||
@test length(arima_model.model.ϵ_t.θ) == 1 | ||
@test arima_model.model.damp_prior == | ||
filldist(truncated(Normal(0.0, 0.05), 0, 1), 1) | ||
@test arima_model.model.ϵ_t.θ == | ||
filldist(truncated(Normal(0.0, 0.05), -1, 1), 1) | ||
|
||
# Test with custom parameters | ||
ar_init_prior = Normal(1.0, 0.5) | ||
diff_init_prior = Normal(0.0, 0.3) | ||
damp_prior = truncated(Normal(0.0, 0.04), 0, 1) | ||
θ_prior = truncated(Normal(0.0, 0.06), -1, 1) | ||
|
||
custom_arima = arima(; | ||
ar_init = [ar_init_prior, ar_init_prior], | ||
diff_init = [diff_init_prior, diff_init_prior], | ||
damp = [damp_prior, damp_prior], | ||
θ = [θ_prior, θ_prior], | ||
ϵ_t = HierarchicalNormal() | ||
) | ||
|
||
@test custom_arima isa DiffLatentModel | ||
@test custom_arima.model isa AR | ||
@test custom_arima.model.ϵ_t isa MA | ||
@test length(custom_arima.model.damp_prior) == 2 | ||
@test length(custom_arima.model.init_prior) == 2 | ||
@test length(custom_arima.model.ϵ_t.θ) == 2 | ||
@test custom_arima.model.damp_prior == filldist(damp_prior, 2) | ||
@test custom_arima.model.init_prior == filldist(ar_init_prior, 2) | ||
@test custom_arima.model.ϵ_t.θ == filldist(θ_prior, 2) | ||
end | ||
|
||
@testitem "Testing ARIMA process against theoretical properties" begin | ||
using DynamicPPL, Turing | ||
using HypothesisTests: ExactOneSampleKSTest, pvalue | ||
using Distributions | ||
using Statistics | ||
|
||
# Set up simple ARIMA model | ||
arima_model = arima() | ||
n = 1000 | ||
damp = [0.1] | ||
σ_AR = 1.0 | ||
ar_init = [0.0] | ||
diff_init = [0.0] | ||
θ = [0.2] # Add MA component | ||
|
||
# Generate and fix model parameters | ||
model = generate_latent(arima_model, n) | ||
fixed_model = fix(model, | ||
( | ||
std = σ_AR, | ||
damp_AR = damp, | ||
ar_init = ar_init, | ||
diff_init = diff_init, | ||
θ = θ | ||
)) | ||
|
||
# Generate samples | ||
n_samples = 100 | ||
samples = sample(fixed_model, Prior(), n_samples; progress = false) |> | ||
chn -> mapreduce(vcat, generated_quantities(fixed_model, chn)) do gen | ||
gen | ||
end | ||
|
||
# Compare with pure AR with differencing | ||
ar_base = AR() | ||
ar_model = DiffLatentModel(; model = ar_base, init_priors = [Normal()]) | ||
ar_fixed = fix( | ||
generate_latent(ar_model, n), | ||
(std = σ_AR, damp_AR = damp, ar_init = ar_init, diff_init = diff_init) | ||
) | ||
|
||
ar_samples = sample(ar_fixed, Prior(), n_samples; progress = false) |> | ||
chn -> mapreduce(vcat, generated_quantities(ar_fixed, chn)) do gen | ||
gen | ||
end | ||
|
||
# Test that ARIMA produces different distribution than pure differenced AR | ||
# This tests that the MA component has an effect | ||
ks_test = ExactOneSampleKSTest(samples, fit(Normal, ar_samples)) | ||
@test pvalue(ks_test) < 1e-6 | ||
|
||
# Test for stationarity of differences | ||
diff_samples = diff(samples) | ||
@test isapprox(mean(diff_samples), 0.0, atol = 0.1) | ||
@test std(diff_samples) > 0 | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
@testitem "Testing ARMA constructor" begin | ||
using Distributions, Turing | ||
|
||
# Test default constructor | ||
arma_model = arma() | ||
@test arma_model isa AR | ||
@test arma_model.ϵ_t isa MA | ||
@test length(arma_model.damp_prior) == 1 | ||
@test length(arma_model.init_prior) == 1 | ||
@test length(arma_model.ϵ_t.θ) == 1 | ||
@test arma_model.damp_prior == filldist(truncated(Normal(0.0, 0.05), 0, 1), 1) | ||
@test arma_model.ϵ_t.θ == filldist(truncated(Normal(0.0, 0.05), -1, 1), 1) | ||
|
||
# Test with custom parameters | ||
damp_prior = truncated(Normal(0.0, 0.04), 0, 1) | ||
θ_prior = truncated(Normal(0.0, 0.06), 0, 1) | ||
init_prior = Normal(1.0, 0.5) | ||
|
||
custom_arma = arma(; | ||
init = [init_prior, init_prior], | ||
damp = [damp_prior, damp_prior], | ||
θ = [θ_prior, θ_prior], | ||
ϵ_t = HierarchicalNormal() | ||
) | ||
|
||
@test custom_arma isa AR | ||
@test custom_arma.ϵ_t isa MA | ||
@test length(custom_arma.damp_prior) == 2 | ||
@test length(custom_arma.init_prior) == 2 | ||
@test length(custom_arma.ϵ_t.θ) == 2 | ||
@test custom_arma.damp_prior == filldist(damp_prior, 2) | ||
@test custom_arma.init_prior == filldist(init_prior, 2) | ||
@test custom_arma.ϵ_t.θ == filldist(θ_prior, 2) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
@testitem "Testing IID constructor" begin | ||
using Distributions, Turing | ||
|
||
normal_prior = Normal(0.0, 1.0) | ||
idd_process = IID(normal_prior) | ||
|
||
@test idd_process.ϵ_t == normal_prior | ||
end | ||
|
||
@testitem "Test IID defaults" begin | ||
using Distributions | ||
idd = IID() | ||
@test idd.ϵ_t == Normal(0, 1) | ||
end | ||
|
||
@testitem "Test IID with different distributions" begin | ||
using Distributions | ||
|
||
@testset "Uniform distribution" begin | ||
idd = IID(Uniform(0, 1)) | ||
sample = rand(idd.ϵ_t) | ||
@test 0 <= sample <= 1 | ||
end | ||
|
||
@testset "Exponential distribution" begin | ||
idd = IID(Exponential(1)) | ||
sample = rand(idd.ϵ_t) | ||
@test sample >= 0 | ||
end | ||
end | ||
|
||
@testitem "Testing IID process against theoretical properties" begin | ||
using DynamicPPL, Turing | ||
using HypothesisTests: ExactOneSampleKSTest, pvalue | ||
using Distributions | ||
|
||
idd_model = IID(Normal(2, 3)) | ||
n = 1000 | ||
|
||
model = generate_latent(idd_model, n) | ||
|
||
n_samples = 100 | ||
samples = sample(model, Prior(), n_samples; progress = false) |> | ||
chn -> mapreduce(vcat, generated_quantities(model, chn)) do gen | ||
gen | ||
end | ||
|
||
theoretical_mean = 2.0 | ||
theoretical_var = 3.0^2 | ||
|
||
@test isapprox(mean(samples), theoretical_mean, atol = 0.1) | ||
@test isapprox(var(samples), theoretical_var, atol = 0.2) | ||
|
||
ks_test_pval = ExactOneSampleKSTest( | ||
samples, Normal(theoretical_mean, sqrt(theoretical_var))) |> pvalue | ||
@test ks_test_pval > 1e-6 | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
@testitem "Testing MA constructor" begin | ||
using Distributions, Turing | ||
|
||
θ_prior = truncated(Normal(0.0, 0.05), -1, 1) | ||
ma_process = MA(θ_prior; q = 1, ϵ_t = HierarchicalNormal()) | ||
|
||
@test ma_process.q == 1 | ||
@test ma_process.ϵ_t isa HierarchicalNormal | ||
@test length(ma_process.θ) == 1 | ||
end | ||
|
||
@testitem "Test MA(2)" begin | ||
using Distributions, Turing | ||
θ_prior = truncated(Normal(0.0, 0.05), -1, 1) | ||
ma = MA(; | ||
θ_priors = [θ_prior, θ_prior], | ||
ϵ_t = HierarchicalNormal() | ||
) | ||
@test ma.q == 2 | ||
@test ma.ϵ_t isa HierarchicalNormal | ||
@test length(ma.θ) == 2 | ||
end | ||
|
||
@testitem "Testing MA process against theoretical properties" begin | ||
using DynamicPPL, Turing | ||
using HypothesisTests: ExactOneSampleKSTest, pvalue | ||
using Distributions | ||
|
||
# Test MA(1) process | ||
θ = [0.1] | ||
@testset "MA(1) with θ = $θ" begin | ||
ma_model = MA(; θ_priors = [truncated(Normal(0.0, 0.05), -1, 1)], | ||
ϵ_t = IID(Normal())) | ||
n = 1000 | ||
model = generate_latent(ma_model, n) | ||
fixed_model = fix(model, (θ = θ,)) | ||
|
||
n_samples = 100 | ||
samples = sample(fixed_model, Prior(), n_samples; progress = false) |> | ||
chn -> mapreduce(vcat, generated_quantities(fixed_model, chn)) do gen | ||
gen | ||
end | ||
|
||
# For MA(1), mean should be 0 | ||
@test isapprox(mean(samples), 0.0, atol = 0.1) | ||
|
||
# For MA(1) with standard normal errors, variance is 1 + θ^2 | ||
theoretical_var = 1 + sum(θ .^ 2) | ||
@test isapprox(var(samples), theoretical_var, atol = 0.2) | ||
|
||
# Test distribution is approximately normal | ||
ks_test = ExactOneSampleKSTest( | ||
samples, Normal(0.0, sqrt(theoretical_var))) | ||
@test pvalue(ks_test) > 1e-6 | ||
end | ||
|
||
# Test MA(2) process | ||
θ = [0.3, 0.2] | ||
@testset "MA(2) with θ = $θ" begin | ||
ma_model = MA(; θ_priors = fill(truncated(Normal(0.0, 0.05), -1, 1), 2), | ||
ϵ_t = IID(Normal())) | ||
n = 1000 | ||
model = generate_latent(ma_model, n) | ||
fixed_model = fix(model, (θ = θ,)) | ||
|
||
n_samples = 100 | ||
samples = sample(fixed_model, Prior(), n_samples; progress = false) |> | ||
chn -> mapreduce(vcat, generated_quantities(fixed_model, chn)) do gen | ||
gen | ||
end | ||
|
||
# For MA(2), mean should be 0 | ||
@test isapprox(mean(samples), 0.0, atol = 0.1) | ||
|
||
# For MA(2) with standard normal errors, variance is 1 + θ_1^2 + θ_2^2 | ||
theoretical_var = 1 + sum(θ .^ 2) | ||
@test isapprox(var(samples), theoretical_var, atol = 0.2) | ||
|
||
# Test distribution is approximately normal | ||
ks_test = ExactOneSampleKSTest( | ||
samples, Normal(0.0, sqrt(theoretical_var))) | ||
@test pvalue(ks_test) > 1e-6 | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
let | ||
model = arima() | ||
mdl = generate_latent(model, 10) | ||
suite["arima"] = make_epiaware_suite(mdl) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
let | ||
model = arma() | ||
mdl = generate_latent(model, 10) | ||
suite["arma"] = make_epiaware_suite(mdl) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
let | ||
model = IID() | ||
mdl = generate_latent(model, 10) | ||
suite["IID"] = make_epiaware_suite(mdl) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
let | ||
latent = MA() | ||
mdl = generate_latent(latent, 10) | ||
suite["MA"] = make_epiaware_suite(mdl) | ||
end |