% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/method-diagnostics.R
\name{diagnostics}
\alias{diagnostics}
\alias{diagnostics,INLAvaan-method}
\title{Convergence and Approximation Diagnostics for INLAvaan Models}
\usage{
diagnostics(object, ...)

\S4method{diagnostics}{INLAvaan}(object, type = c("global", "param"), ...)
}
\arguments{
\item{object}{An object of class \link{INLAvaan}.}

\item{...}{Currently unused.}

\item{type}{Character. \code{"global"} (default) returns a named numeric
vector of scalar diagnostics. \code{"param"} returns a data frame with one
row per free parameter containing per-parameter diagnostics.}
}
\value{
For \code{type = "global"}, a named numeric vector (class
\code{"diagnostics.INLAvaan"}). For \code{type = "param"}, a data frame
(class \code{c("diagnostics.INLAvaan.param", "data.frame")}).
}
\description{
Extract convergence and approximation-quality diagnostics from a fitted
\code{INLAvaan} model.
}
\details{
\strong{Global diagnostics} (\code{type = "global"}):
\describe{
\item{\code{npar}}{Number of free parameters.}
\item{\code{nsamp}}{Number of posterior samples drawn.}
\item{\code{converged}}{1 if the optimiser converged, 0 otherwise.}
\item{\code{iterations}}{Number of optimiser iterations.}
\item{\code{grad_inf}}{L-infinity norm of the analytic gradient at the mode
(max |grad|). Should be ~0 at convergence.}
\item{\code{grad_inf_rel}}{Relative L-infinity norm of the analytic gradient
(max |grad| / (|par| + 1e-6)).}
\item{\code{grad_l2}}{L2 (Euclidean) norm of the analytic gradient at the mode.}
\item{\code{mode_shift_max}}{Maximum, across parameters, of the Newton
step at the reported mode in posterior-SD units
(max |\eqn{\Sigma_\theta} grad| / se). Unlike the raw gradient norms
this is scale-free: it estimates how far the reported mode sits from
the true posterior mode relative to the posterior uncertainty. Should
be ~0 at convergence.}
\item{\code{hess_cond}}{Condition number of the Hessian (precision matrix)
computed from \eqn{\Sigma_\theta}. Large values indicate near-singularity.}
\item{\code{vb_kld_global}}{Global KL divergence from the VB mean correction
(NA if VB correction was not applied).}
\item{\code{vb_applied}}{1 if VB correction was applied, 0 otherwise.}
\item{\code{kld_max}}{Maximum per-parameter KL divergence from the VB correction.}
\item{\code{kld_mean}}{Mean per-parameter KL divergence.}
\item{\code{nmad_max}}{Maximum normalised max-absolute-deviation across
marginals (skew-normal method only; NA otherwise).}
\item{\code{nmad_mean}}{Mean NMAD across marginals.}
}

\strong{Per-parameter diagnostics} (\code{type = "param"}):
A data frame with columns:
\describe{
\item{\code{param}}{Parameter name.}
\item{\code{grad}}{Analytic gradient of the negative log-posterior at the
mode. Should be ~0 at convergence.}
\item{\code{grad_num}}{Numerical (finite-difference) gradient at the mode.
Should agree with \code{grad}; large discrepancies indicate a bug in the
analytic gradient.}
\item{\code{grad_diff}}{Difference \code{grad_num - grad}: should be ~0.}
\item{\code{grad_abs}}{Absolute analytic gradient.}
\item{\code{grad_rel}}{Relative analytic gradient |grad| / (|par| + 1e-6).}
\item{\code{mode_shift_sigma}}{Newton step at the reported mode in
posterior-SD units. Should be ~0 at convergence.}
\item{\code{kld}}{Per-parameter KL divergence from the VB correction.}
\item{\code{vb_shift}}{VB correction shift (in original scale).}
\item{\code{vb_shift_sigma}}{VB shift in units of posterior SD.}
\item{\code{nmad}}{Normalised max-absolute-deviation of the skew-normal fit
(NA when not using the skewnorm method).}
}

\strong{Fit-time warnings}: \code{\link[=inlavaan]{inlavaan()}} runs these checks once at the end
of every fit and emits a single consolidated warning (condition class
\code{"inlavaan_diagnostics_warning"}) when any of them look off: the
optimiser did not converge, \code{mode_shift_max} exceeds 0.1,
any marginal has NMAD above 0.1, the VB correction shifted a posterior
mean by more than 1 posterior SD, or the Hessian condition number exceeds
1e8. A healthy fit stays silent. Silence the check with
\code{suppressWarnings()}, or selectively by handling the condition class.
}
\examples{
\donttest{
HS.model <- "
  visual  =~ x1 + x2 + x3
  textual =~ x4 + x5 + x6
  speed   =~ x7 + x8 + x9
"
utils::data("HolzingerSwineford1939", package = "lavaan")
fit <- acfa(HS.model, HolzingerSwineford1939, std.lv = TRUE, nsamp = 100,
            test = "none", verbose = FALSE)

# Global convergence summary
diagnostics(fit)

# Per-parameter table
diagnostics(fit, type = "param")
}

}
\seealso{
\code{\link[=timing]{timing()}}, \code{\link[=fitmeasures]{fitmeasures()}}, \code{\link[=plot]{plot()}}
}
