% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/vbpm_fit.R
\name{vbpm_fit}
\alias{vbpm_fit}
\alias{vbpm_fit-class}
\title{The vbpm_fit class: what it is and why it exists}
\description{
Every estimator in \code{vbpm} returns its results with an S3 class attached:
\code{\link[=vbfa]{vbfa()}} returns \code{c("vbfa", "vbpm_fit")} and \code{\link[=vbmimic]{vbmimic()}} returns
\code{c("vbmimic", "vbpm_fit")}. This page explains what that means in
practice, because "S3 class" sounds like more machinery than it is.
}
\section{What an S3 class actually is}{

An S3 class is nothing more than a \strong{label attached to an ordinary R
object}. A \code{vbpm_fit} is still a plain named list -- the class attribute
changes none of its contents and none of the ways you already use it:
\itemize{
\item \code{fit$Lam}, \code{fit$eta}, \code{fit$ELBO}, ... work exactly as before;
\item \code{names(fit)} lists every component;
\item \code{str(fit)} shows the full structure;
\item \code{unclass(fit)} strips the label and gives back the bare list, should you
ever want it.
}

The label does exactly two things. First, generic functions such as
\code{\link[=print]{print()}} can now \strong{dispatch}: typing \code{fit} at the console no longer
floods the screen with every matrix in the object, but shows a compact
summary (model type, dimensions, convergence, ELBO, active loadings).
Second, functions receiving a fit can \strong{recognize what it is}: this is
how \code{\link[=fit_stats]{fit_stats()}} knows a bifactor fit from an oblique one without being told
(the fit carries its own \code{orthogonal} and \code{ld} settings), and how it sends a
\code{\link[=vbmimic]{vbmimic()}} fit to its own method. That method, \code{fit_stats.vbmimic()},
returns a populated but deliberately limited result -- \code{NA} for every
SEM-like index, plus a single \code{n_active_coef} count of soft-selected
measurement and structural coefficients -- because the MIMIC objective and
joint covariance derivation those indices need are not available yet. It is
the family fallback \code{fit_stats.vbpm_fit()} that stops instead of computing
something meaningless, and it applies to classes with no method of their
own.
}

\section{Why the family shares a parent class}{

The specific class (\code{"vbfa"}, \code{"vbmimic"}) comes first, the family class
\code{"vbpm_fit"} second. Methods written for \code{vbpm_fit} therefore apply to
every model in the family unless a model overrides them -- one \code{print}
method serves all estimators, and future family members (e.g. further
variational models) inherit sensible behaviour on day one.
}

\section{Why two classes rather than one class plus a model field}{

A natural-looking alternative is a single \code{"vbpm_fit"} class with a field
saying which model it is. The field exists -- every fit carries
\verb{$model} (\code{"vbfa"} or \code{"vbmimic"}), and it is the right thing to \emph{read}
when a script wants to branch on model type. But it cannot replace the
class vector, because the class vector is what R's method dispatch runs
on. With the two-element class, model-specific behaviour is added by
writing a method (\code{fit_stats.vbmimic()}), the family default by writing
\code{fit_stats.vbpm_fit()}, and a future model (say \code{vblvm}) joins by
returning \code{c("vblvm", "vbpm_fit")} and adding only the methods where it
differs -- including from outside this package. With a single class, every
generic would have to contain a hand-written \code{switch(object$model, ...)}
that this package alone can extend, and \code{inherits(fit, "vbfa")} would stop
working. This is the same convention base R uses: a \code{glm} object has class
\code{c("glm", "lm")}, not class \code{"lm"} with a family field. So: dispatch on the
classes, read \verb{$model} for display and bookkeeping.
}

\section{What is deliberately NOT hidden}{

Some R packages wrap results in opaque objects whose internals are
discouraged territory. \code{vbpm} does the opposite: the list components are
documented in each estimator's help page (\code{?vbfa}, \code{?vbmimic}) and are
part of the public API. The class adds convenience on top; it takes
nothing away.
}

\seealso{
\code{\link[=vbfa]{vbfa()}}, \code{\link[=vbmimic]{vbmimic()}}, \code{\link[=print.vbpm_fit]{print.vbpm_fit()}}
}
