Nothing
#' @srrstats {G5.4, G5.4a, G5.4b, G5.4c, G5.9b} Tests that the approximation
#' coincides with KFAS and in GLM case results coincide with the glm.
context("Test Gaussian approximation")
test_that("Gaussian approximation results of bssm and KFAS coincide", {
suppressWarnings(library(KFAS))
set.seed(123)
model_KFAS <- SSModel(rpois(10, exp(2)) ~ SSMtrend(2, Q = list(1, 1),
P1 = diag(100, 2)), distribution = "poisson")
expect_error(model_bssm <- bsm_ng(model_KFAS$y, sd_level = 1,
sd_slope = 1, distribution = "poisson"), NA)
approx_KFAS <- approxSSM(model_KFAS)
expect_error(approx_bssm <- gaussian_approx(model_bssm), NA)
expect_equivalent(c(approx_bssm$H^2), c(approx_KFAS$H))
expect_error(alphahat <- fast_smoother(approx_bssm), NA)
expect_equivalent(KFS(approx_KFAS)$alphahat, alphahat)
expect_equivalent(logLik(approx_KFAS), logLik(approx_bssm))
model_KFAS <- SSModel(rbinom(10, 10, 0.5) ~ SSMtrend(2, Q = list(1, 1),
P1 = diag(100, 2)), u = 10, distribution = "binomial")
expect_error(model_bssm <- bsm_ng(model_KFAS$y, sd_level = 1,
sd_slope = 1, distribution = "binomial", u = 10), NA)
approx_KFAS <- approxSSM(model_KFAS)
expect_error(approx_bssm <- gaussian_approx(model_bssm), NA)
expect_equivalent(c(approx_bssm$H^2), c(approx_KFAS$H))
expect_error(alphahat <- fast_smoother(approx_bssm), NA)
expect_equivalent(KFS(approx_KFAS)$alphahat, alphahat)
expect_equivalent(logLik(approx_KFAS), logLik(approx_bssm))
model_bssm$initial_mode[] <- model_bssm$initial_mode + rnorm(10, sd = 0.1)
expect_equivalent(logLik(gaussian_approx(model_bssm)),
logLik(approx_bssm), tol = 0.001)
})
test_that("Gaussian approximation works for SV model", {
set.seed(123)
expect_error(model_bssm <- svm(rnorm(5), sigma = uniform(1, 0, 10),
rho = uniform(0.950, 0, 1),
sd_ar = uniform(0.1, 0, 1)), NA)
expect_error(approx_bssm <- gaussian_approx(model_bssm, max_iter = 2,
conv_tol = 1e-8), NA)
expect_equivalent(c(-1.47548927809174, -11.2190916117862,
0.263154138901814, -121.519769682058, -36.0386937004332),
approx_bssm$y[1:5])
expect_equivalent(c(2.01061310553144, 4.84658294043645, 0.712674409714633,
15.6217737012134, 8.54936618861792), approx_bssm$H[1:5])
expect_equivalent(c(-0.0999179077423753, -0.101594935319188,
-0.0985572218431492, -0.103275329248674, -0.103028083292436),
fast_smoother(approx_bssm)[1:5])
model_bssm2 <- model_bssm
model_bssm2$initial_mode[] <- model_bssm$initial_mode + rnorm(5, sd = 0.1)
expect_equivalent(logLik(gaussian_approx(model_bssm)),
logLik(gaussian_approx(model_bssm2)), tol = 0.001)
})
test_that("results for poisson GLM are equal to glm function", {
d <- data.frame(treatment = gl(3, 3), outcome = gl(3, 1, 9),
counts = c(18, 17, 15, 20, 10, 20, 25, 13, 12))
glm_poisson <- glm(counts ~ outcome + treatment, data = d,
family = poisson())
xreg <- model.matrix(~ outcome + treatment, data = d)
expect_error(model_poisson1 <- ssm_ung(d$counts, Z = t(xreg), T = diag(5),
R = diag(0, 5),
P1 = diag(1e7, 5), distribution = "poisson",
state_names = colnames(xreg)), NA)
expect_error(sm <- smoother(model_poisson1), NA)
expect_equal(sm$alphahat[1, ], coef(glm_poisson))
expect_equal(sm$V[, , 1], vcov(glm_poisson))
xreg <- model.matrix(~ outcome + treatment, data = d)[, -1]
expect_error(model_poisson2 <- bsm_ng(d$counts, sd_level = 0, xreg = xreg,
P1 = matrix(1e7),
beta = normal(coef(glm_poisson)[-1], 0, 10), distribution = "poisson"), NA)
expect_equivalent(smoother(model_poisson2)$alphahat[1, ],
coef(glm_poisson)[1])
model_poisson3 <- model_poisson1
model_poisson3$P1[] <- 0
model_poisson3$P1[1] <- 1e7
model_poisson3$a1[2:5] <- coef(glm_poisson)[-1]
model_poisson4 <- ssm_ung(d$counts, Z = 1, T = 1, R = 0,
D = t(model_poisson2$xreg %*% model_poisson2$beta),
P1 = 1e7, distribution = "poisson")
expect_equivalent(gaussian_approx(model_poisson1)$y,
gaussian_approx(model_poisson2)$y)
expect_equivalent(gaussian_approx(model_poisson1)$y,
gaussian_approx(model_poisson3)$y)
expect_equivalent(gaussian_approx(model_poisson1)$y,
gaussian_approx(model_poisson4)$y)
expect_equivalent(gaussian_approx(model_poisson1)$H,
gaussian_approx(model_poisson2)$H)
expect_equivalent(gaussian_approx(model_poisson1)$H,
gaussian_approx(model_poisson3)$H)
expect_equivalent(gaussian_approx(model_poisson1)$H,
gaussian_approx(model_poisson4)$H)
})
test_that("results for binomial GLM are equal to glm function", {
ldose <- rep(0:5, 2)
numdead <- c(1, 4, 9, 13, 18, 20, 0, 2, 6, 10, 12, 16)
sex <- factor(rep(c("M", "F"), c(6, 6)))
SF <- cbind(numdead, numalive = 20 - numdead)
glm_binomial <- glm(SF ~ sex * ldose, family = binomial)
xreg <- model.matrix(~ sex * ldose)
expect_error(model_binomial <- ssm_ung(numdead, Z = t(xreg),
T = diag(4), R = diag(0, 4), P1 = diag(1e5, 4),
distribution = "binomial", u = 20, state_names = colnames(xreg)), NA)
expect_error(sm <- smoother(model_binomial), NA)
# non-exact diffuse initialization is numerically difficult...
expect_equal(sm$alphahat[1, ], coef(glm_binomial), tolerance = 1e-5)
expect_equal(sm$V[, , 1], vcov(glm_binomial), tolerance = 1e-4)
})
test_that("state estimates for NB GLM are equal to glm function", {
library(MASS)
set.seed(123)
offs <- quine$Days + sample(10:20, size = nrow(quine), replace = TRUE)
glm_nb <- glm.nb(Days ~ 1 + offset(log(offs)), data = quine)
expect_error(model_nb <- bsm_ng(quine$Days, u = offs, sd_level = 0,
P1 = matrix(1e7), phi = glm_nb$theta,
distribution = "negative binomial"), NA)
approx_model <- gaussian_approx(model_nb, conv_tol = 1e-12)
expect_error(sm <- smoother(approx_model), NA)
expect_equivalent(sm$alphahat[1], unname(coef(glm_nb)[1]))
})
test_that("Two iid model gives same results as two univariate models", {
set.seed(1)
y <- matrix(rbinom(20, size = 10, prob = plogis(rnorm(20, sd = 0.5))), 10, 2)
expect_error(model <- ssm_mng(y, Z = diag(2), phi = 2,
T = diag(2), R = array(diag(0.5, 2), c(2, 2, 1)),
a1 = matrix(0, 2, 1), P1 = diag(2), distribution = "negative binomial",
init_theta = c(0, 0)), NA)
expect_error(model1 <- ssm_ung(y[, 1], Z = 1, phi = 2,
T = 1, R = 0.5, P1 = 1, distribution = "negative binomial",
init_theta = 0), NA)
expect_error(model2 <- ssm_ung(y[, 2], Z = 1, phi = 2,
T = 1, R = 0.5, P1 = 1, distribution = "negative binomial",
init_theta = 0), NA)
expect_equivalent(gaussian_approx(model, conv_tol = 1e-12)$y,
cbind(gaussian_approx(model1, conv_tol = 1e-12)$y,
gaussian_approx(model2, conv_tol = 1e-12)$y), tol = 1e-6)
})
test_that("Gaussian approximation works for nonlinear models", {
skip_on_cran()
pntrs <- cpp_example_model("nlg_linear_gaussian")
set.seed(1)
y <- cumsum(rnorm(10)) + rnorm(10)
model_nlg <- ssm_nlg(y = y, a1 = pntrs$a1, P1 = pntrs$P1,
Z = pntrs$Z_fn, H = pntrs$H_fn, T = pntrs$T_fn, R = pntrs$R_fn,
Z_gn = pntrs$Z_gn, T_gn = pntrs$T_gn,
theta = c(log_H = 0), log_prior_pdf = pntrs$log_prior_pdf,
n_states = 1, n_etas = 1, state_names = "state")
model_gaussian <- bsm_lg(y, sd_y = 1, sd_level = 1, P1 = 1)
expect_equal(
logLik(model_nlg, method = "ekf", particles = 0),
logLik(gaussian_approx(model_nlg)))
expect_equal(logLik(model_gaussian), logLik(gaussian_approx(model_nlg)))
set.seed(1)
n <- 30
x <- y <- numeric(n)
y[1] <- rnorm(1, exp(x[1]), 0.1)
for(i in 1:(n-1)) {
x[i+1] <- rnorm(1, sin(x[i]), 0.1)
y[i+1] <- rnorm(1, exp(x[i+1]), 0.1)
}
y[2:5] <- NA
pntrs <- cpp_example_model("nlg_sin_exp")
expect_error(model_nlg <- ssm_nlg(y = y, a1 = pntrs$a1, P1 = pntrs$P1,
Z = pntrs$Z_fn, H = pntrs$H_fn, T = pntrs$T_fn, R = pntrs$R_fn,
Z_gn = pntrs$Z_gn, T_gn = pntrs$T_gn,
theta = c(log_H = log(0.1), log_R = log(0.1)),
log_prior_pdf = pntrs$log_prior_pdf,
n_states = 1, n_etas = 1, state_names = "state"), NA)
expect_equal(gaussian_approx(model_nlg),
gaussian_approx(model_nlg, max_iter = 2))
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.