% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/sim_mirt.R
\name{sim_mirt}
\alias{sim_mirt}
\title{Simulate Multidimensional Item Response Theory Data}
\usage{
sim_mirt(
  n_people = 1000,
  item_structure = list(),
  dimension = 2,
  theta = NULL,
  theta_mean = 0,
  Sigma = NULL
)
}
\arguments{
\item{n_people}{Integer. Number of examinees.}

\item{item_structure}{List of lists defining item blocks (see Details).}

\item{dimension}{Integer. Number of latent dimensions (D).}

\item{theta}{Numeric matrix (Optional). An \code{n_people} x \code{dimension}
matrix of abilities. If supplied it is used directly.}

\item{theta_mean}{Numeric. Mean of the latent traits, recycled across
dimensions (used when \code{theta} is \code{NULL}).}

\item{Sigma}{Numeric matrix (Optional). A \code{dimension} x \code{dimension}
covariance matrix for the latent traits (used when \code{theta} is
\code{NULL}). Defaults to the identity matrix (uncorrelated dimensions).}
}
\value{
A list containing:
\item{resp}{data.frame of responses (rows = people, cols = items).}
\item{true_params}{data.frame of true item parameters, including one
\code{a_Dim} column per dimension, the intercept \code{d}, guessing, and
step/threshold columns for polytomous items.}
\item{theta}{the \code{n_people} x \code{dimension} matrix of true abilities.}
}
\description{
Simulates responses from compensatory multidimensional item response models,
the multidimensional counterpart of \code{\link{sim_irt}}. It supports the
multidimensional binary models estimated by \code{\link{mirt_binary}}
(M-Rasch, M-2PL, M-3PL) as well as multidimensional polytomous models
(multidimensional GPCM and GRM). Each block of items may load on any subset of
the latent dimensions, so both simple-structure and complex-structure designs
are easy to generate.
}
\details{
Each element of \code{item_structure} is a list describing one block:
\itemize{
\item \code{model}: one of \code{"M2PL"}, \code{"M3PL"}, \code{"MRasch"}
(dichotomous) or \code{"MGPCM"}, \code{"MGRM"} (polytomous). The
non-prefixed names (\code{"2PL"}, \code{"GRM"}, ...) are also accepted.
\item \code{n_items}: number of items in the block.
\item \code{dims}: integer vector of the dimensions the block loads on
(default: all dimensions). Slopes on the remaining dimensions are 0.
\item \code{a}: discrimination/slope, given as a range \code{c(lo, hi)} to
sample from, or a single fixed value (default \code{c(0.8, 1.8)}).
\item \code{d}: intercept, given as a range or a fixed value (default
\code{c(-1.5, 1.5)}). Note the compensatory model uses the intercept
metric \eqn{z = a'\theta + d}, matching \code{mirt_binary()}.
\item \code{c}: lower asymptote for \code{"M3PL"} (default \code{0.2}).
\item \code{categories}: number of categories for polytomous blocks
(default \code{3}).
}
}
\examples{
  # Two correlated dimensions, simple structure
  set.seed(2025)
  Sigma <- matrix(c(1, 0.4, 0.4, 1), 2, 2)

  design <- list(
    list(model = "M2PL", n_items = 8, dims = 1),          # loads on Dim 1
    list(model = "M2PL", n_items = 8, dims = 2),          # loads on Dim 2
    list(model = "M3PL", n_items = 4, dims = c(1, 2), c = 0.2)  # both dims
  )

  sim <- sim_mirt(n_people = 500, item_structure = design,
                  dimension = 2, Sigma = Sigma)

  head(sim$resp)
  head(sim$true_params)

  \donttest{
  # Recover with the multidimensional estimator
  Q <- as.matrix(sim$true_params[, c("a_Dim1", "a_Dim2")] != 0) * 1
  fit <- mirt_binary(sim$resp, model = "2PL", dimension = 2,
                     control = list(Q_matrix = Q, max_iter = 10, verbose = FALSE))
  head(fit$item_params)
  }
}
\seealso{
\code{\link{mirt_binary}}, \code{\link{sim_irt}}
}
