tests/testthat/test_ml_estimation.R

library("testthat")


# vertex representation (one prediction per row)
V <- matrix(c(
  # strict weak orders
  0, 1, 0, 1, 0, 1, # a < b < c
  1, 0, 0, 1, 0, 1, # b < a < c
  0, 1, 0, 1, 1, 0, # a < c < b
  0, 1, 1, 0, 1, 0, # c < a < b
  1, 0, 1, 0, 1, 0, # c < b < a
  1, 0, 1, 0, 0, 1, # b < c < a

  0, 0, 0, 1, 0, 1, # a ~ b < c
  0, 1, 0, 0, 1, 0, # a ~ c < b
  1, 0, 1, 0, 0, 0, # c ~ b < a
  0, 1, 0, 1, 0, 0, # a < b ~ c
  1, 0, 0, 0, 0, 1, # b < a ~ c
  0, 0, 1, 0, 1, 0, # c < a ~ b

  0, 0, 0, 0, 0, 0 # a ~ b ~ c
), byrow = TRUE, ncol = 6)

# transform to Ab-representation
# Ab <- V_to_Ab(V)

# for CRAN: use pre-computed solution
Ab <- list(
  A = structure(
    c(
      -1, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 1, 0,
      0, 1, 0, -1, 0, 0, 0, 0, 0, 0, -1, -1, 1, 0, 0, 0, 1, 0, 0, -1,
      0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 0, 0, -1,
      0, 0, 1, -1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 1, 0, -1,
      0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 1, 0, 0, -1, 0, -1, 1, 0, 0
    ),
    .Dim = c(15L, 6L)
  ),
  b = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1)
)

test_that("ML estimation matches for Ab- and V-representation", {
  set.seed(123)
  k <- c(4, 1, 5, 1, 9, 0, 7, 2, 1)
  options <- c(3, 3, 3)

  est_V <- ml_multinom(
    k = k, options = options, V = V,
    n.fit = 5, control = list(maxit = 1e6, reltol = .Machine$double.eps^.6),
    outer.iterations = 1000
  )


  est_Ab <- ml_multinom(
    k = k, options = options, A = Ab$A, b = Ab$b,
    n.fit = 5, control = list(maxit = 1e6, reltol = .Machine$double.eps^.6),
    outer.iterations = 1000
  )

  expect_equal(unname(est_V$p), est_Ab$par, tolerance = .0001)
})

test_that("if unconstrained MLE == constrained MLE", {
  set.seed(123)
  n <- 100
  m <- 5
  options <- rep(3, m)
  V <- round(rpdirichlet(n, rep(1, 3 * 5), options = options))
  alpha <- c(rpdirichlet(1, rep(1, n), n, drop_fixed = FALSE))
  p <- add_fixed(c(alpha %*% V), options)
  k <- c(round(p * 10000))
  n <- c(tapply(k, rep(1:length(options), options), sum))
  mle_unconstr <- drop_fixed(k / n, options)

  t <- system.time(
    est_V <- ml_multinom(
      k = k, options = options, V = unique(V),
      n.fit = 5, control = list(maxit = 1e7, reltol = .Machine$double.eps^.5),
      outer.iterations = 1000, progress = FALSE
    )
  )["elapsed"]
  expect_lt(t, 1) # should be fast!
  expect_equal(est_V$p, mle_unconstr, tolerance = .0001)
  expect_equal(est_V$value, multinomineq:::loglik_multinom(mle_unconstr, k, options))
})

Try the multinomineq package in your browser

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

multinomineq documentation built on Nov. 22, 2022, 5:09 p.m.