# Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

#' Compute Gauss-Hermite quadrature nodes and weights
#'
#' @param n Number of quadrature points
#' @return List with nodes and weights
#' @export
gauss_hermite_quadrature <- function(n) {
    .Call(`_factorana_gauss_hermite_quadrature`, n)
}

#' Initialize a FactorModel C++ object from R model system
#'
#' @param model_system R model_system object
#' @param data Data frame or matrix with all variables
#' @param n_quad Number of quadrature points
#' @param init_params Optional initial parameter vector (used to set fixed parameter values)
#' @return External pointer to FactorModel object
#' @export
initialize_factor_model_cpp <- function(model_system, data, n_quad = 8L, init_params = NULL) {
    .Call(`_factorana_initialize_factor_model_cpp`, model_system, data, n_quad, init_params)
}

#' Evaluate log-likelihood for given parameters
#'
#' @param fm_ptr External pointer to FactorModel object
#' @param params Vector of parameters
#' @param compute_gradient Whether to compute gradient (default FALSE)
#' @param compute_hessian Whether to compute Hessian (default FALSE)
#' @return List with:
#'   - logLikelihood: scalar log-likelihood value
#'   - gradient: vector of length n_param_free (if requested)
#'   - hessian: vector of length n_param_free*(n_param_free+1)/2 stored as
#'              upper-triangular in row-major order (if requested).
#'              To expand to full symmetric matrix in R:
#'              \code{idx <- 1; for(i in 1:n) for(j in i:n) { H[i,j] <- H[j,i] <- hess[idx]; idx <- idx + 1 }}
#' @export
evaluate_likelihood_cpp <- function(fm_ptr, params, compute_gradient = FALSE, compute_hessian = FALSE) {
    .Call(`_factorana_evaluate_likelihood_cpp`, fm_ptr, params, compute_gradient, compute_hessian)
}

#' Evaluate log-likelihood only (for optimization)
#'
#' @param fm_ptr External pointer to FactorModel object
#' @param params Vector of parameters
#' @return Log-likelihood value
#' @export
evaluate_loglik_only_cpp <- function(fm_ptr, params) {
    .Call(`_factorana_evaluate_loglik_only_cpp`, fm_ptr, params)
}

#' Get parameter counts from FactorModel
#'
#' @param fm_ptr External pointer to FactorModel object
#' @return List with parameter count information
#' @export
get_parameter_info_cpp <- function(fm_ptr) {
    .Call(`_factorana_get_parameter_info_cpp`, fm_ptr)
}

#' Extract free parameters from full parameter vector
#'
#' Given a full parameter vector (including fixed parameters),
#' extract only the free parameters based on the model's fixed parameter mask.
#'
#' @param fm_ptr External pointer to FactorModel object
#' @param full_params Full parameter vector (size n_param)
#' @return Vector of free parameters only (size n_param_free)
#' @export
extract_free_params_cpp <- function(fm_ptr, full_params) {
    .Call(`_factorana_extract_free_params_cpp`, fm_ptr, full_params)
}

#' Set observation weights for weighted likelihood estimation
#'
#' Sets per-observation weights for the likelihood calculation. When weights
#' are set, each observation's contribution to the log-likelihood is multiplied
#' by its weight. This is used for importance sampling in adaptive integration.
#'
#' @param fm_ptr External pointer to FactorModel object
#' @param weights Numeric vector of observation weights (length = n_obs)
#' @return No return value. Called for its side effect of setting the
#'   per-observation likelihood weights on the FactorModel pointed to by
#'   \code{fm_ptr}.
#' @export
set_observation_weights_cpp <- function(fm_ptr, weights) {
    invisible(.Call(`_factorana_set_observation_weights_cpp`, fm_ptr, weights))
}

#' Set up adaptive quadrature based on factor scores and standard errors
#'
#' Enables adaptive integration where the number of quadrature points varies
#' by observation based on the precision of factor score estimates. When factor
#' scores are well-determined (small SE), fewer integration points are used.
#' Importance sampling weights are computed automatically.
#'
#' @param fm_ptr External pointer to FactorModel object
#' @param factor_scores Matrix (n_obs x n_factors) of factor score estimates
#' @param factor_ses Matrix (n_obs x n_factors) of standard errors
#' @param factor_vars Vector (n_factors) of factor variances from previous stage
#' @param threshold Threshold for determining quadrature points (default 0.5, matching legacy)
#' @param max_quad Maximum quadrature points per factor (default 16)
#' @param verbose Whether to print summary of adaptive quadrature setup (default TRUE)
#' @return No return value. Called for its side effect of enabling adaptive
#'   quadrature on the FactorModel pointed to by \code{fm_ptr} and (when
#'   \code{verbose = TRUE}) printing a summary of the per-observation
#'   integration-point distribution.
#' @export
set_adaptive_quadrature_cpp <- function(fm_ptr, factor_scores, factor_ses, factor_vars, threshold = 0.5, max_quad = 16L, verbose = TRUE) {
    invisible(.Call(`_factorana_set_adaptive_quadrature_cpp`, fm_ptr, factor_scores, factor_ses, factor_vars, threshold, max_quad, verbose))
}

#' Disable adaptive quadrature
#'
#' Reverts to standard (non-adaptive) quadrature integration.
#'
#' @param fm_ptr External pointer to FactorModel object
#' @return No return value. Called for its side effect of disabling adaptive
#'   quadrature and clearing any observation weights on the FactorModel
#'   pointed to by \code{fm_ptr}.
#' @export
disable_adaptive_quadrature_cpp <- function(fm_ptr) {
    invisible(.Call(`_factorana_disable_adaptive_quadrature_cpp`, fm_ptr))
}

#' Evaluate log-likelihood for a single observation at given factor values
#'
#' Used for factor score estimation. The model parameters are held fixed,
#' and the factor values are treated as the parameters to optimize.
#'
#' @param fm_ptr External pointer to FactorModel object
#' @param iobs Observation index (0-based)
#' @param factor_values Vector of factor values (size n_factors)
#' @param model_params Vector of ALL model parameters (from previous estimation)
#' @param compute_gradient Whether to compute gradient (default FALSE)
#' @param compute_hessian Whether to compute Hessian (default FALSE)
#' @param include_prior Whether to include factor prior in likelihood (default TRUE).
#'        Set to FALSE to match legacy C++ behavior (observation likelihood only).
#' @return List with log-likelihood, gradient (if requested), and Hessian (if requested)
#' @export
evaluate_factorscore_likelihood_cpp <- function(fm_ptr, iobs, factor_values, model_params, compute_gradient = FALSE, compute_hessian = FALSE, include_prior = TRUE) {
    .Call(`_factorana_evaluate_factorscore_likelihood_cpp`, fm_ptr, iobs, factor_values, model_params, compute_gradient, compute_hessian, include_prior)
}

