context("MarkovChain class") # Create MarkovChain object for tests n <- 100 data <- data.frame(x1 = rnorm(n), x2 = rnorm(n)) f <- ~ x1 + s(x2, k = 5, bs = "cs") mc <- MarkovChain$new(n_states = 2, formula = f, data = data) test_that("Parameter transformation functions cancel out", { tpm <- matrix(c(0.9, 0.1, 0.3, 0.7), ncol = 2, byrow = TRUE) # Transform to linear predictor scale par <- mc$tpm2par(tpm) # Transform back to tpm tpm2 <- mc$par2tpm(par) expect_equal(tpm, tpm2) }) test_that("Simulation output is as expected", { nsim <- 50 sim <- mc$simulate(n = nsim, data = data, silent = TRUE) # Check length of output expect_equal(length(sim), nsim) # Check that output is in state space expect_equal(sort(unique(sim)), c(1, 2)) }) test_that("Model matrices have the right format", { terms <- mc$terms() expect_equal(dim(terms$X_fe), c(2*n, 4)) expect_equal(dim(terms$X_re), c(2*n, 8)) expect_equal(dim(terms$S), c(8, 8)) }) test_that("Model terms are consistent", { terms <- mc$terms() expect_equal(sum(terms$ncol_fe), ncol(terms$X_fe)) expect_equal(sum(apply(terms$ncol_re, 2, function(x) diff(x) + 1)), ncol(terms$X_re)) }) test_that("linpred has correct length", { expect_equal(length(mc$linpred()), 2*n) }) test_that("TPM has correct dimensions", { expect_equal(dim(mc$tpm()), c(2, 2, 1)) expect_equal(dim(mc$tpm(t = 5)), c(2, 2, 1)) expect_equal(dim(mc$tpm(t = 6:10)), c(2, 2, 5)) expect_equal(dim(mc$tpm(t = "all")), c(2, 2, n)) expect_equal(dim(mc$tpm(t = "all", linpred = seq(-2, 2, length = 4))), c(2, 2, 2)) }) test_that("Stationary distribution has correct dimensions", { expect_equal(dim(mc$delta()), c(1, 2)) expect_equal(dim(mc$delta(t = 5)), c(1, 2)) expect_equal(dim(mc$delta(t = 6:10)), c(5, 2)) expect_equal(dim(mc$delta(t = "all")), c(n, 2)) expect_equal(dim(mc$delta(t = "all", linpred = seq(-2, 2, length = 4))), c(2, 2)) }) test_that("Update methods work", { # Test update of delta and tpm new_delta0 <- c(0.3, 0.7) mc$update_delta0(delta0 = new_delta0) expect_equal(unname(c(mc$delta0())), new_delta0) new_tpm <- matrix(c(0.8, 0.3, 0.2, 0.7), ncol = 2) mc$update_tpm(tpm = new_tpm) expect_equal(unname(mc$tpm()[,,1]), new_tpm) # Re-initialise object mc <- MarkovChain$new(n_states = 2, formula = f, data = data) # Test update of coeff_fe/re new_fe <- 1:4 new_re <- seq(-3, 3, length = 8) mc$update_coeff_fe(coeff_fe = new_fe) mc$update_coeff_re(coeff_re = new_re) expect_equal(c(mc$coeff_fe()), new_fe) expect_equal(c(mc$coeff_re()), new_re) # Test update of lambda new_lambda <- c(2, 5) mc$update_lambda(lambda = new_lambda) expect_equal(c(mc$lambda()), new_lambda) # Re-initialise object mc <- MarkovChain$new(n_states = 2, formula = f, data = data) }) test_that("delta is computed correctly", { # Check stationary distribution for a few special cases of TPM mc$update_tpm(tpm = matrix(c(0.5, 0.5, 0.5, 0.5), ncol = 2)) expect_equal(unname(mc$delta()[1,]), c(0.5, 0.5)) mc$update_tpm(tpm = matrix(c(0.9, 0.1, 0.1, 0.9), ncol = 2)) expect_equal(unname(mc$delta()[1,]), c(0.5, 0.5)) mc$update_tpm(tpm = matrix(c(0.9, 0.2, 0.1, 0.8), ncol = 2)) expect_equal(unname(mc$delta()[1,]), c(2/3, 1/3)) mc$update_tpm(tpm = matrix(c(0.9, 0.3, 0.1, 0.7), ncol = 2)) expect_equal(unname(mc$delta()[1,]), c(3/4, 1/4)) mc$update_tpm(tpm = matrix(c(0.9, 0.4, 0.1, 0.6), ncol = 2)) expect_equal(unname(mc$delta()[1,]), c(4/5, 1/5)) mc$update_tpm(tpm = matrix(c(0.9, 0.5, 0.1, 0.5), ncol = 2)) expect_equal(unname(mc$delta()[1,]), c(5/6, 1/6)) mc$update_tpm(tpm = matrix(c(0.1, 0.1, 0.9, 0.9), ncol = 2)) expect_equal(unname(mc$delta()[1,]), c(0.1, 0.9)) # Check that error is throw for singular system mc$update_tpm(tpm = matrix(c(1, 0, 0, 1), ncol = 2)) expect_error(mc$delta(), "singular system") # Re-initialise object mc <- MarkovChain$new(n_states = 2, formula = f, data = data) })