| genpca | R Documentation |
Implements the Generalised Least-Squares Matrix Decomposition of Allen, Grosenick & Taylor (2014) for data observed in a row inner-product space M and a column inner-product space A. Setting M = I_n, A = I_p recovers ordinary PCA.
genpca(
X,
A = NULL,
M = NULL,
ncomp = NULL,
method = c("eigen", "auto", "spectra", "randomized", "deflation"),
constraints_remedy = c("error", "ridge", "clip", "identity"),
preproc = multivarious::pass(),
threshold = 1e-06,
maxit_deflation = 500L,
use_cpp = TRUE,
maxeig = 5000,
warn_approx = TRUE,
maxit_spectra = 1000,
tol_spectra = 1e-09,
rank_rtol = 1e-06,
oversample = 20L,
n_power = 1L,
n_polish = 0L,
jitter_metric = 1e-10,
seed_randomized = 1234L,
tol_polish_randomized = 1e-04,
verbose = FALSE
)
X |
Numeric matrix n x p. |
A |
Column constraint: vector (implies diagonal), dense matrix, or sparse
symmetric p x p PSD matrix. If |
M |
Row constraint: vector (implies diagonal), dense matrix, or sparse
symmetric n x n PSD matrix. If |
ncomp |
Number of components to extract. Defaults to |
method |
Character string specifying the computation method. One of |
constraints_remedy |
Character string specifying what to do with a
supplied |
preproc |
Pre-processing transformer object from the multivarious package
(default |
threshold |
Convergence tolerance for the |
maxit_deflation |
Maximum iterations per component for the
|
use_cpp |
Logical. If |
maxeig |
For |
warn_approx |
Deprecated and ignored: |
maxit_spectra |
Retained for compatibility and currently unused: the
eigencore partial SVD used by |
tol_spectra |
Convergence tolerance of the iterative solver when
|
rank_rtol |
Relative cutoff for component acceptance, on the scale of
the singular values: component |
oversample |
Oversampling for |
n_power |
Number of power iterations for |
n_polish |
Number of optional block-polish iterations for |
jitter_metric |
Relative Gram jitter for the candidate Cholesky
preconditioner in |
seed_randomized |
Optional seed for |
tol_polish_randomized |
Relative tolerance used for early stopping of polish iterations in |
verbose |
Logical. If |
An object of class c("genpca", "bi_projector") inheriting from multivarious::bi_projector,
with slots including:
Left/right singular vectors scaled by the constraint metrics
(MU, AV). These correspond to components in the original space's geometry.
Use components(fit).
Orthonormal singular vectors in the constraint metric (U, V such that UT M U = I, VT AV = I). These are the core mathematical factors.
Generalised singular values d_k. Note these are singular
values of the metric-whitened data matrix, not standard
deviations: with identity metrics and centering,
sdev = prcomp(X)$sdev * sqrt(nrow(X) - 1).
Scores: the generalised principal components
z_k = X A ov_k = ou_k d_k (Allen et al. 2014, Section 2.4).
Identical to project(fit, X) on the training data.
Use scores(fit).
The multivarious pre-processing object used.
The constraint matrices used (potentially after coercion to sparse format).
Proportion of generalized variance explained by each component.
Cumulative proportion of generalized variance explained.
We compute the rank-ncomp factors UDVT that minimise
\|X - UDV^\top\|_{M,A}^2
= \mathrm{tr}\!\bigl(M\, (X-UDV^\top)\,A\,(X-UDV^\top)^\top\bigr)
subject to UT M U = I, VT AV = I. (Allen et al., 2014).
Five methods are available via the method argument:
"eigen" (Default): Uses a one-shot eigen decomposition strategy based on gmdLA. It explicitly forms and decomposes a p \times p or n \times n matrix (depending on n vs p).
"auto": Chooses among "eigen", "spectra", and "randomized" using heuristics on shape, rank ratio (ncomp / min(n,p)), and constraint structure.
"spectra": Computes the top-k singular triplets of the metric-whitened data F_M' X F_A (with M = F_M F_M', A = F_A F_A') as an implicit operator via the eigencore package, without forming the large intermediate matrix. Generally faster and uses less memory for large n or p when few components are requested.
"randomized": Uses a randomized block range finder and small projected eigendecomposition. This is an approximate low-pass method that is often much faster for wide dense matrices with sparse metrics when only top components are needed.
"deflation": Uses an iterative power/deflation algorithm. Can be slower but potentially uses less memory than "eigen" for very large dense problems where ncomp is small.
The default is method = "eigen"; "auto" is opt-in, not the
default.
Use "eigen" (the default) when you need a stable reference solution on small/medium problems.
Use "auto" to let a heuristic pick among "eigen", "spectra", and "randomized" based on problem shape and constraint structure.
Use "spectra" for larger matrix-free iterative solves where memory pressure is a concern.
Use "randomized" for wide low-rank settings (p >> n) with sparse metrics when throughput matters most.
Use "deflation" when you only need a few components and can tolerate iterative convergence behavior.
For pre-computed covariance matrices C = X'MX, see genpca_cov which
performs GPCA directly on C with column constraint R (equivalent to A).
Allen, G. I., Grosenick, L., & Taylor, J. (2014). A Generalized Least-Squares Matrix Decomposition. Journal of the American Statistical Association, 109(505), 145-159. arXiv:1102.3074.
genpca_cov for GPCA on pre-computed covariance matrices,
truncate.genpca, reconstruct.genpca,
multivarious::bi_projector, multivarious::project, multivarious::scores,
multivarious::components, multivarious::reconstruct.
if (requireNamespace("multivarious", quietly = TRUE)) {
set.seed(123)
X <- matrix(stats::rnorm(200 * 100), 200, 100)
rownames(X) <- paste0("R", 1:200)
colnames(X) <- paste0("C", 1:100)
# Standard PCA (A=I, M=I, centered) - using default method="eigen"
gpca_std_eigen <- genpca(X, ncomp = 5, preproc = multivarious::center(), verbose = FALSE)
# Standard PCA using Spectra method (requires C++ build)
# gpca_std_spectra <- try(genpca(X, ncomp = 5,
# preproc = multivarious::center(),
# method = "spectra", verbose = TRUE))
# if (!inherits(gpca_std_spectra, "try-error")) {
# print(head(gpca_std_spectra$sdev))
# }
# Compare singular values with prcomp
pr_std <- stats::prcomp(X, center = TRUE, scale. = FALSE)
print("Eigen Method Sdev:")
print(head(gpca_std_eigen$sdev))
print("prcomp Sdev:")
print(head(pr_std$sdev))
print(paste("Total Var Explained (Eigen):",
round(sum(gpca_std_eigen$propv) * 100), "%"))
# Weighted column PCA (diagonal A, no centering)
col_weights <- stats::runif(100, 0.5, 1.5)
gpca_weighted <- genpca(X, A = col_weights, ncomp = 3,
preproc = multivarious::pass(), verbose = FALSE)
print("Weighted GPCA Sdev:")
print(gpca_weighted$sdev)
print(head(components(gpca_weighted)))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.