% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/get.fit.index.FCDCM.R,
%   R/get.fit.index.FCGDINA.R, R/get.fit.index.FCGGUM.R,
%   R/get.fit.index.FCMIRT.R, R/get.fit.index.MGGUM.R, R/get.fit.index.MGPCM.R,
%   R/get.fit.index.MIRT.R, R/get.fit.index.R, R/get.fit.index.TIRT.R
\name{get.fit.index.FCDCM}
\alias{get.fit.index.FCDCM}
\alias{get.fit.index.FCGDINA}
\alias{get.fit.index.FCGGUM}
\alias{get.fit.index.FCMIRT}
\alias{get.fit.index.MGGUM}
\alias{get.fit.index.MGPCM}
\alias{get.fit.index.MIRT}
\alias{get.fit.index}
\alias{get.fit.index.TIRT}
\title{Goodness-of-Fit Indices for Fitted Models}
\usage{
\method{get.fit.index}{FCDCM}(object, ...)

\method{get.fit.index}{FCGDINA}(object, ...)

\method{get.fit.index}{FCGGUM}(object, ...)

\method{get.fit.index}{FCMIRT}(object, ...)

\method{get.fit.index}{MGGUM}(object, ...)

\method{get.fit.index}{MGPCM}(object, ...)

\method{get.fit.index}{MIRT}(object, ...)

\method{get.fit.index}{TIRT}(object, ...)
}
\arguments{
\item{object}{A fitted model object (class \code{"MIRT"}, \code{"MGPCM"},
\code{"MGGUM"}, \code{"FCMIRT"}, \code{"FCDCM"}, \code{"FCGGUM"}, or
\code{"TIRT"}).}

\item{...}{Additional arguments passed to \code{\link{good.of.fit}}.
Common options include \code{alpha} (tail probability for RMSEA CI;
default 0.05 gives a 90\% CI), \code{bivariate.groups} (exclude pairs
within the same group from bivariate moments), and \code{n.boot}
(bootstrap replicates).}
}
\value{
An object of class \code{"good.of.fit"}. Use
\code{\link{summary.good.of.fit}} and \code{\link{print.good.of.fit}}
for formatted output. Key components:
\itemize{
\item \code{LogLik}, \code{deviance}, \code{AIC}, \code{AICc},
\code{BIC}, \code{CAIC}, \code{SABIC}, \code{HQIC}
\item \code{M2.value}, \code{df}, \code{p.value}
\item \code{RMSEA2}, \code{RMSEA.lower}, \code{RMSEA.upper},
\code{RMSEA.p.close}
\item \code{SRMSR}
\item \code{CFI}, \code{TLI}, \code{IFI}
\item \code{McFadden.R2}, \code{CoxSnell.R2}, \code{Nagelkerke.R2}
\item \code{q3.mean}, \code{q3.abs.max}, \code{q3.adjusted.abs.max}
\item \code{posterior.entropy}, \code{posterior.entropy.normalized}
}
}
\description{
Generic function to compute a comprehensive suite of model-fit diagnostics
for fitted ForceChoice model objects. The function dispatches on the class
of the fitted model and returns an object of class \code{"good.of.fit"}
containing likelihood-based, limited-information, and residual-based
diagnostics.
}
\section{Methods (by class)}{
\itemize{
\item \code{get.fit.index(FCDCM)}: FCDCM model: binary block responses with
quadrature over higher-order \eqn{\theta} and exact marginalization
over \eqn{2^D} attribute patterns.

\item \code{get.fit.index(FCGDINA)}: FCGDINA model: forced-choice CDM with nominal
binary expansion; within-block pairs excluded.

\item \code{get.fit.index(FCGGUM)}: FCGGUM model: forced-choice unfolding with nominal
binary expansion; within-block pairs excluded.

\item \code{get.fit.index(FCMIRT)}: FCMIRT model: forced-choice ranking data expanded
to nominal binary indicators; within-block pairs excluded from bivariate
moments.

\item \code{get.fit.index(MGGUM)}: MGGUM model: polytomous unfolding responses with
M2* category-collapsed construction.

\item \code{get.fit.index(MGPCM)}: MGPCM model: polytomous responses with M2*
category-collapsed construction.

\item \code{get.fit.index(MIRT)}: MIRT model: binary responses with Gauss--Hermite
quadrature over \eqn{D}-dimensional latent space.

\item \code{get.fit.index(TIRT)}: TIRT model: pairwise binary responses with
within-block pairs excluded via \code{bivariate.groups}.

}}
\section{Limited-Information M2 Framework}{


Following Maydeu-Olivares and Joe (2005, 2006), the test statistic uses
first- and second-order marginal moments rather than the full contingency
table, making it suitable for sparse high-dimensional responses.

Let \eqn{\boldsymbol{\pi}(\boldsymbol{\psi})} be the vector of
\eqn{M} model-implied univariate and bivariate moments,
\eqn{\mathbf{p}} the observed moments, and
\eqn{\boldsymbol{\Delta} = \partial\boldsymbol{\pi}/\partial\boldsymbol{\psi}'}
the Jacobian. The M2 statistic is:
\deqn{
  M_2 = N\,\mathbf{e}'\hat{\mathbf{C}}_2\mathbf{e},
  \qquad \mathbf{e} = \mathbf{p} - \boldsymbol{\pi}(\hat{\boldsymbol{\psi}}),
}
where \eqn{\hat{\mathbf{C}}_2 = \boldsymbol{\Delta}_c
(\boldsymbol{\Delta}_c'\hat{\boldsymbol{\Xi}}_2\boldsymbol{\Delta}_c)^{-1}
\boldsymbol{\Delta}_c'} with \eqn{\boldsymbol{\Delta}_c} the orthogonal
complement of \eqn{\boldsymbol{\Delta}}. Under the null,
\eqn{M_2 \sim \chi^2_{M - p}} asymptotically.
}

\section{Fit Index Formulas}{


\strong{Information criteria} (Akaike 1974; Schwarz 1978; Bozdogan 1987;
Sclove 1987; Hannan & Quinn 1979):
\deqn{
  \begin{aligned}
  \text{AIC}   &= -2\ell + 2p, \\
  \text{AICc}  &= \text{AIC} + \frac{2p(p+1)}{N-p-1}, \\
  \text{BIC}   &= -2\ell + p\log N, \\
  \text{CAIC}  &= -2\ell + p(\log N + 1), \\
  \text{SABIC} &= -2\ell + p\log\!\bigl(\frac{N+2}{24}\bigr), \\
  \text{HQIC}  &= -2\ell + 2p\log(\log N).
  \end{aligned}
}

\strong{RMSEA} (Browne & Cudeck 1993):
\deqn{
  \text{RMSEA} = \sqrt{\max\!\left(0,\; \frac{M_2 - df}{N \cdot df}\right)},
  \qquad df = M - p.
}
Confidence intervals via non-central \eqn{\chi^2} inversion; close-fit
test \eqn{H_0: \text{RMSEA} \le 0.05}.

\strong{SRMSR:}
\deqn{
  \text{SRMSR} = \sqrt{\frac{1}{J}\sum_{i<j}(r_{ij}^{\text{obs}} - r_{ij}^{\text{model}})^2}.
}

\strong{CFI / TLI / IFI} (Bentler 1990; Tucker & Lewis 1973; Bollen 1989):
\deqn{
  \begin{aligned}
  \text{CFI} &= 1 - \frac{\max(M_2 - df, 0)}{\max(M_2^{\text{null}} - df^{\text{null}},\; M_2 - df,\; 0)}, \\[4pt]
  \text{TLI} &= \frac{M_2^{\text{null}}/df^{\text{null}} - M_2/df}{M_2^{\text{null}}/df^{\text{null}} - 1}, \\[4pt]
  \text{IFI} &= \frac{M_2^{\text{null}} - M_2}{M_2^{\text{null}} - df}.
  \end{aligned}
}

\strong{Pseudo-\eqn{R^2}:}
\deqn{
  \begin{aligned}
  R^2_{\text{McF}}     &= 1 - \ell/\ell_0, \\
  R^2_{\text{CS}}      &= 1 - \exp\!\bigl(\tfrac{2}{N}(\ell_0 - \ell)\bigr), \\
  R^2_{\text{N}}       &= R^2_{\text{CS}} / \bigl(1 - \exp(2\ell_0/N)\bigr), \\
  R^2_{\text{AN}}      &= G^2/(G^2 + N), \quad G^2 = D_0 - D.
  \end{aligned}
}

\strong{Yen's Q3} (Yen 1984):
\deqn{
  Q_{3,ik} = \text{Corr}(r_{ji}, r_{jk}), \qquad
  r_{ji} = Y_{ji} - E[Y_{ji} \mid \hat{\boldsymbol{\theta}}_j].
}

\strong{Posterior diagnostics} (Celeux & Soromenho 1996):
\deqn{
  E = -\frac{1}{N}\sum_{j=1}^{N}\sum_{c=1}^{Q}\hat{\tau}_{jc}\log\hat{\tau}_{jc},
  \qquad
  E_{\text{norm}} = 1 - E / \log Q.
}
}

\section{Heuristic Guidelines}{

\itemize{
\item RMSEA: \eqn{\le 0.05} close, \eqn{\le 0.08} reasonable
\item SRMSR: \eqn{\le 0.08} acceptable (Hu & Bentler 1999)
\item CFI / TLI: \eqn{\ge 0.95} good, \eqn{\ge 0.90} acceptable
\item Normalized entropy: \eqn{\ge 0.70} acceptable separation
}
}

\examples{
sim <- sim.data.MIRT(N = 20, I = 6, D = 2, model = "m2pl")
fit <- fit.MIRT(
  sim$response, model = "m2pl", D = 2, method = "iStEM",
  control.method = list(
    vis = FALSE, seed = 123,
    M = 2, B = 2, burnin.maxitr = 2,
    maxitr = 3, eps1 = 10, eps2 = 10,
    estimate.se = FALSE)
)
gof <- get.fit.index(fit)
summary(gof)

# Custom RMSEA confidence level (99\%)
gof99 <- get.fit.index(fit, alpha = 0.005)
summary(gof99)
}
\references{
Akaike, H. (1974). \emph{IEEE Trans. Autom. Control}, 19, 716--723.
Bozdogan, H. (1987). \emph{Psychometrika}, 52, 345--370.
Browne, M. W., & Cudeck, R. (1993). In Bollen & Long (Eds.), \emph{Testing
structural equation models} (pp. 136--162). Sage.
Celeux, G., & Soromenho, G. (1996). \emph{J. Classification}, 13, 195--212.
Hu, L. T., & Bentler, P. M. (1999). \emph{Struct. Equ. Modeling}, 6, 1--55.
Maydeu-Olivares, A., & Joe, H. (2005). \emph{JASA}, 100, 1009--1020.
Maydeu-Olivares, A., & Joe, H. (2006). \emph{Psychometrika}, 71, 713--732.
Schwarz, G. (1978). \emph{Ann. Statist.}, 6, 461--464.
Yen, W. M. (1984). \emph{Appl. Psychol. Meas.}, 8, 125--145.
}
\seealso{
\code{\link{good.of.fit}} for the underlying engine,
\code{\link{summary.good.of.fit}} for formatted summary tables.
}
