tests/testthat/test-econometric-likelihood.R

test_that("cell probabilities sum to 1 for any valid parameters", {
  set.seed(42)
  n_tests <- 100

  for (i in seq_len(n_tests)) {
    lambdas <- runif(3)
    lambdas <- lambdas / sum(lambdas)
    gamma <- runif(1, 0.1, 0.9)

    g <- gamma
    lgg <- lambdas[1]
    lgk <- lambdas[2]
    lkk <- lambdas[3]

    vec <- numeric(4)
    vec[1] <- (1 - g) * (1 - g) * lgg
    vec[2] <- (1 - g) * g * lgg + (1 - g) * lgk
    vec[3] <- (1 - g) * g * lgg
    vec[4] <- g * g * lgg + g * lgk + lkk

    expect_equal(sum(vec), 1, tolerance = 1e-10)
  }
})

test_that("cell probabilities are non-negative for all valid parameters", {
  set.seed(43)
  n_tests <- 100

  for (i in seq_len(n_tests)) {
    lambdas <- runif(3)
    lambdas <- lambdas / sum(lambdas)
    gamma <- runif(1, 0.01, 0.99)

    g <- gamma
    lgg <- lambdas[1]
    lgk <- lambdas[2]
    lkk <- lambdas[3]

    vec <- numeric(4)
    vec[1] <- (1 - g) * (1 - g) * lgg
    vec[2] <- (1 - g) * g * lgg + (1 - g) * lgk
    vec[3] <- (1 - g) * g * lgg
    vec[4] <- g * g * lgg + g * lgk + lkk

    expect_true(all(vec >= 0))
  }
})

test_that("expected values match likelihood function formulas", {
  gamma_values <- c(0.1, 0.25, 0.5, 0.75, 0.9)
  lambda_sets <- list(
    c(0.4, 0.3, 0.3),
    c(0.6, 0.2, 0.2),
    c(0.33, 0.33, 0.34),
    c(0.1, 0.1, 0.8)
  )

  for (gamma_i in gamma_values) {
    for (lambdas in lambda_sets) {
      lgg <- lambdas[1]
      lgk <- lambdas[2]
      lkk <- lambdas[3]

      lik_vec <- numeric(4)
      lik_vec[1] <- (1 - gamma_i) * (1 - gamma_i) * lgg
      lik_vec[2] <- (1 - gamma_i) * gamma_i * lgg + (1 - gamma_i) * lgk
      lik_vec[3] <- (1 - gamma_i) * gamma_i * lgg
      lik_vec[4] <- gamma_i * gamma_i * lgg + gamma_i * lgk + lkk

      expected <- calculate_expected_values(gamma_i, lambdas, 1, "nodk")

      expect_equal(expected, lik_vec, tolerance = 1e-12)
    }
  }
})

test_that("negative log-likelihood is minimized near true parameters", {
  skip_if(
    Sys.getenv("GUESS_FULL_TESTS") != "true",
    "Extended tests require GUESS_FULL_TESTS=true"
  )

  set.seed(123)
  n <- 1000

  true_lambdas <- c(0.4, 0.3, 0.3)
  true_gamma <- 0.25

  counts <- generate_transition_counts(n, true_lambdas, true_gamma)
  data_vec <- as.numeric(counts)

  true_nll <- guess_lik(c(true_lambdas, true_gamma), data = data_vec)

  perturbations <- list(
    c(0.5, 0.25, 0.25, 0.25),
    c(0.35, 0.35, 0.30, 0.30),
    c(0.4, 0.3, 0.3, 0.40),
    c(0.2, 0.4, 0.4, 0.15)
  )

  for (pert in perturbations) {
    pert_nll <- guess_lik(pert, data = data_vec)
    expect_true(
      pert_nll >= true_nll - 0.5,
      info = paste("Perturbed params:", paste(pert, collapse = ", "))
    )
  }
})

test_that("DK model cell probabilities are non-negative", {
  set.seed(44)
  n_tests <- 50

  for (i in seq_len(n_tests)) {
    lambdas <- runif(7)
    lambdas <- lambdas / sum(lambdas)
    gamma <- runif(1, 0.1, 0.9)

    g <- gamma
    lgg <- lambdas[1]
    lgk <- lambdas[2]
    lgd <- lambdas[3]
    lkg <- lambdas[4]
    lkk <- lambdas[5]
    lkd <- lambdas[6]
    ldd <- lambdas[7]

    vec <- numeric(9)
    vec[1] <- (1 - g) * (1 - g) * lgg
    vec[2] <- (1 - g) * g * lgg + (1 - g) * lgk
    vec[3] <- (1 - g) * lgd
    vec[4] <- (1 - g) * g * lgg + lkg
    vec[5] <- g * g * lgg + g * lgk + g * lkg + lkk
    vec[6] <- g * lgd + lkd
    vec[7] <- lkg
    vec[8] <- g * lgk + lkd
    vec[9] <- ldd

    expect_true(all(vec >= 0))
  }
})

Try the guess package in your browser

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

guess documentation built on March 31, 2026, 9:07 a.m.