% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mbinary.R
\name{mirt_binary}
\alias{mirt_binary}
\title{Multidimensional Binary Item Response Theory Estimation}
\usage{
mirt_binary(
  data,
  model = "2PL",
  dimension = 2,
  method = "MML",
  control = list()
)
}
\arguments{
\item{data}{A N x J data.frame or matrix of dichotomous responses (0/1).}

\item{model}{String. "Rasch", "2PL", or "3PL".}

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

\item{method}{String. Estimation method: "MML" (Marginal Maximum Likelihood with EM, best for D <= 3),
"MHRM" (Metropolis-Hastings Robbins-Monro, for high D), or "RVEM" (Dimension-Reduction EM).}

\item{control}{A \code{list} of control parameters for the estimation algorithm:
\itemize{
\item \code{max_iter}: Maximum number of iterations (default = 100).
\item \code{converge_tol}: Convergence criterion (default = 1e-4).
\item \code{theta_range}: Bounds for quadrature integration (default = c(-4, 4)).
\item \code{quad_points}: Quadrature points PER DIMENSION for MML (default = 15).
\item \code{ability}: Logical; estimate person abilities (EAP) after item calibration? (default = TRUE).
\item \code{verbose}: Logical; prints progress and psychometric messages.
\item \code{Q_matrix}: Optional J x D matrix of 0s and 1s indicating item-to-dimension loading.
If NULL, an exploratory lower-triangular constraint is applied for identifiability.
}}
}
\value{
A list containing:
\itemize{
\item \code{item_params}: A data frame of estimated item parameters (a_1...a_D, d, g) and standard errors.
\item \code{person_params}: A data frame of estimated multidimensional person abilities (if ability=TRUE).
\item \code{model_fit}: Fit statistics (Log-Likelihood, AIC, BIC).
\item \code{settings}: Control parameters used in the run.
}
}
\description{
Estimates item and person parameters for multidimensional binary item response models
(M-Rasch, M-2PL, M-3PL). The function is fully self-contained, using custom Newton-Raphson
optimization without relying on external optimizers.
}
\examples{

  # --- Simulation for Multidimensional Data ---
  set.seed(202)
  N <- 800
  J <- 20
  D <- 2

  # Simulate Abilities (2 Dimensions, correlated)
  Sigma <- matrix(c(1, 0.4, 0.4, 1), 2, 2)
  Z <- matrix(rnorm(N * D), N, D)
  theta <- Z \%*\% chol(Sigma)

  # Define Q-matrix (Items 1-10 on Dim1, Items 11-20 on Dim 2)
  Q <- matrix(0, J, D)
  Q[1:10, 1] <- 1
  Q[11:20, 2] <- 1

  # Simulate Item Parameters (Multidimensional 2PL)
  a_true <- matrix(runif(J * D, 0.8, 1.8), J, D) * Q
  d_true <- seq(-2, 2, length.out = J)

  # Generate Responses
  data_mat <- matrix(NA, N, J)
  for(i in 1:N) {
    # Matrix multiply JxD slopes by Dx1 person abilities, add Jx1 intercepts
    z <- as.vector(a_true \%*\% theta[i, ]) + d_true
    p <- 1 / (1 + exp(-z))
    data_mat[i, ] <- rbinom(J, 1, p)
  }
  df <- as.data.frame(data_mat)
  names(df) <- paste0("Item", 1:J)

  # --- Run Custom Multidimensional Function ---
  res <- mirt_binary(df, model="2PL", dimension=2, method="MML",
                     control=list(Q_matrix=Q, ability=TRUE, max_iter=10))

  print(head(res$item_params))
  print(head(res$person_params))
  print(res$model_fit)
  \donttest{
  # --- Validation with 'mirt' (For comparison, if installed) ---
  # library(mirt)
  # mirt_model <- paste0("F1 = 1-10\nF2 = 11-20\nCOV = F1*F2")
  # mirt_res <- mirt(df, mirt.model(mirt_model), itemtype='2PL', method='EM')
  # coef(mirt_res, IRTpars=FALSE, simplify=TRUE)$items
  }
}
