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

#' Compute number of non-matching indicator-to-factor correspondences
#'
#' @param x numeric matrix. A matrix of pattern coefficients.
#' @param y numeric matrix. A second matrix of coefficients.
#' @param thresh numeric. The threshold to classify a pattern coefficient as substantial.
.factor_corres <- function(x, y, thresh = 0.3) {
    .Call(`_EFAtools_factor_corres`, x, y, thresh)
}

.grad_ml <- function(psi, R, n_fac) {
    .Call(`_EFAtools_grad_ml`, psi, R, n_fac)
}

.error_ml <- function(psi, R, n_fac) {
    .Call(`_EFAtools_error_ml`, psi, R, n_fac)
}

#' Get reference values for nest.
#'
#' Function called from within NEST so usually no call to this is needed by the user.
#' Provides a C++ implementation of the NEST simulation procedure
#'
#' @param nf numeric. Current number of factors.
#' @param N numeric. Number of cases / observations in dataset.
#' @param M numeric matrix. A transposed matrix of cbind(loadings, diag(sqrt(uniquenesses))).
#' @param nreps numeric. Number of datasets to create.
.nest_sym <- function(nf, N, M, nreps = 1000L) {
    .Call(`_EFAtools_nest_sym`, nf, N, M, nreps)
}

#' Oblique Procrustes target rotation using a k x k inner objective
#'
#' Compute an oblique target rotation for a loading matrix using a
#' `targetQ`-compatible parameterization and a `k x k` objective.
#'
#' The rotated loading matrix is defined as
#' `L = A %*% solve(t(T))`, and the corresponding factor correlation matrix is
#' `Phi = t(T) %*% T`. The optimization is carried out over the transformation
#' matrix `T` under the oblique normalization constraint `diag(t(T) %*% T) = 1`.
#'
#' The line search is monotone: a candidate is accepted only if it satisfies the
#' sufficient-decrease condition, or, as a numerical fallback, if it at least
#' decreases the objective after all step halvings are exhausted. Non-invertible
#' candidate transformations are rejected rather than evaluated through a
#' pseudo-inverse.
#'
#' Additional random starts may be requested. To reduce runtime, the solver uses
#' a two-stage strategy for extra starts: cheap objective screening, followed by
#' short triage optimization, followed by full optimization only for starts that
#' improve on the current incumbent by at least `triage_improve_tol`.
#'
#' @param A Numeric matrix. Loading matrix to be rotated.
#' @param B Numeric matrix. Target loading matrix with the same dimensions as
#'   `A`.
#' @param S_r Optional numeric `k x k` matrix containing `crossprod(A)`.
#'   Supplying this is useful when the same `A` is rotated repeatedly. Ignored
#'   when `normalize = TRUE` because the normalized cross-product is different.
#' @param T_init_r Optional numeric `k x k` starting transformation matrix.
#'   If `NULL`, the identity matrix is used for the primary start.
#' @param eps Numeric scalar. Convergence tolerance for the projected-gradient
#'   norm.
#' @param maxit Integer scalar. Maximum number of full projected-gradient
#'   updates.
#' @param max_line_search Integer scalar. Maximum number of step-halving
#'   attempts after the initial trial step in each line-search phase.
#' @param step0 Numeric scalar. Initial step size used in the projected-gradient
#'   update.
#' @param normalize Logical scalar. If `TRUE`, apply Kaiser normalization before
#'   rotation and reverse it after rotation.
#' @param random_starts Integer scalar. Number of additional random starts.
#' @param screen_keep Integer scalar. Number of screened random starts retained
#'   for triage optimization.
#' @param triage_maxit Integer scalar. Number of short optimization iterations
#'   used in the triage stage.
#' @param triage_improve_tol Numeric scalar. Relative improvement required for a
#'   triaged start to be promoted to full optimization.
#'
#' @returns A named list containing the rotated loadings, transformation matrix,
#'   factor correlation matrix, target criterion value, convergence diagnostics,
#'   line-search diagnostics, and multi-start summaries.
#'
#' @details
#' The routine is intended for repeated oblique target rotations in workflows
#' such as bootstrap alignment or consensus alignment of exploratory factor
#' solutions across multiply imputed datasets. It follows the same oblique
#' transformation convention as `GPArotation::targetQ()`.
#'
#' @references
#' Bernaards, C. A., & Jennrich, R. I. (2005). Gradient projection algorithms
#' and software for arbitrary rotation criteria in factor analysis.
#' *Educational and Psychological Measurement*, 65, 676-696.
#'
#' Gower, J. C. (1975). Generalized Procrustes analysis. *Psychometrika*, 40,
#' 33-51.
#'
.oblique_procrustes <- function(A, B, S_r = NULL, T_init_r = NULL, eps = 1e-5, maxit = 1000L, max_line_search = 10L, step0 = 1.0, normalize = FALSE, random_starts = 0L, screen_keep = 2L, triage_maxit = 25L, triage_improve_tol = 0.0) {
    .Call(`_EFAtools_oblique_procrustes`, A, B, S_r, T_init_r, eps, maxit, max_line_search, step0, normalize, random_starts, screen_keep, triage_maxit, triage_improve_tol)
}

#' Perform the iterative PAF procedure
#'
#' Function called from within PAF so usually no call to this is needed by the user.
#' Provides a C++ implementation of the PAF procedure
#'
#' @param h2 numeric. The initial communality estimates.
#' @param criterion double. The convergence criterion to use.
#' @param R matrix. The correlation matrix with the initial communality estimates in the diagonal.
#' @param n_fac numeric. The number of factors to extract.
#' @param abs_eig logical. Whether absolute eigenvalues should be used to compute the loadings.
#' @param crit_type numeric. Whether maximum absolute differences (crit_type = 1), or sum of differences (crit_type = 2) should be used
#' @param max_iter numeric. The number of iterations after which to end the procedure if no convergence has been reached by then.
.paf_iter <- function(h2, criterion, R, n_fac, abs_eig, crit_type, max_iter) {
    .Call(`_EFAtools_paf_iter`, h2, criterion, R, n_fac, abs_eig, crit_type, max_iter)
}

#' Parallel analysis on simulated data.
#'
#' Function called from within PARALLEL so usually no call to this is needed by the user.
#' Provides a C++ implementation of the PARALLEL simulation procedure
#'
#' @param n_datasets numeric. Number of datasets with dimensions (N, n_vars) to simulate.
#' @param n_vars numeric. Number of variables / indicators in dataset.
#' @param N numeric. Number of cases / observations in dataset.
#' @param eigen_type numeric. Whether PCA (eigen_type = 1; i.e., leaving diagonal of correlation matrix at 1) or PAF (eigen_type = 2; i.e., setting diagonal of correlation matrix to SMCs).
#' @param maxit numeric. Maximum iterations to perform after which to abort.
.parallel_sim <- function(n_datasets, n_vars, N, eigen_type, maxit = 10000L) {
    .Call(`_EFAtools_parallel_sim`, n_datasets, n_vars, N, eigen_type, maxit)
}

.grad_uls <- function(psi, R, n_fac) {
    .Call(`_EFAtools_grad_uls`, psi, R, n_fac)
}

.uls_residuals <- function(psi, R, n_fac) {
    .Call(`_EFAtools_uls_residuals`, psi, R, n_fac)
}

