tests/testthat/test-kalman.R

test_that("Kalman filter produces finite log-likelihood for AR(1)", {
  # Simple AR(1): y_t = z_t, z_{t+1} = rho * z_t + e_t
  G <- matrix(1)
  H <- matrix(0.8)
  M <- matrix(1)
  D <- matrix(1)

  set.seed(42)
  n <- 100
  z <- numeric(n)
  for (i in 2:n) z[i] <- 0.8 * z[i - 1] + rnorm(1)
  y <- matrix(z, ncol = 1)

  kf <- kalman_filter(y, G, H, M, D)

  expect_true(is.finite(kf$loglik))
  expect_true(kf$loglik < 0)
  expect_equal(nrow(kf$filtered_states), n)
  expect_equal(nrow(kf$predicted_obs), n)
})

test_that("Kalman filter handles 2-obs model", {
  G <- diag(2)
  H <- diag(c(0.7, 0.9))
  M <- diag(c(1, 0.5))
  D <- diag(2)

  set.seed(123)
  n <- 100
  z <- matrix(0, n, 2)
  for (i in 2:n) {
    z[i, ] <- H %*% z[i - 1, ] + M %*% rnorm(2)
  }
  y <- z

  kf <- kalman_filter(y, G, H, M, D)

  expect_true(is.finite(kf$loglik))
  expect_equal(ncol(kf$filtered_states), 2)
})

test_that("unconditional P solves Lyapunov equation", {
  H <- matrix(0.8)
  Q <- matrix(1)

  P <- compute_unconditional_P(H, Q)

  # Should satisfy: P = H * P * H' + Q
  check <- H %*% P %*% t(H) + Q
  expect_equal(as.numeric(P), as.numeric(check), tolerance = 1e-10)
})

test_that("Kalman smoother returns valid states", {
  G <- matrix(1)
  H <- matrix(0.8)
  M <- matrix(1)
  D <- matrix(1)

  set.seed(42)
  n <- 50
  z <- numeric(n)
  for (i in 2:n) z[i] <- 0.8 * z[i - 1] + rnorm(1)
  y <- matrix(z, ncol = 1)

  sm <- kalman_smoother(y, G, H, M, D)

  expect_equal(nrow(sm$smoothed_states), n)
  expect_true(all(is.finite(sm$smoothed_states)))
})

Try the dsge package in your browser

Any scripts or data that you put into this service are public.

dsge documentation built on Sept. 25, 2026, 5:08 p.m.