Analytic LOSO contrast using eigenvalue perturbation
Source:R/dkge-analytic.R
dkge_analytic_loso.RdApproximates leave-one-subject-out contrast values using first-order eigenvalue perturbation theory, avoiding full eigen-decomposition per subject.
Arguments
- fit
A `dkge` object from [dkge_fit()]
- s
Subject index (1-based) to leave out
- contrasts
Contrast vector in the original design basis (length q)
- tol
Numerical tolerance for determining when to fall back to full eigen
- fallback
If TRUE, fall back to full eigen when perturbation may be unstable
- ridge
Ridge regularization parameter (default 0)
Value
List with fields: - `v`: Cluster contrast values for subject s - `alpha`: Contrast coordinates in latent space - `basis`: Approximated held-out basis U^(-s) - `method`: "analytic" or "fallback" if full eigen was used
Details
This function implements the first-order eigenvalue perturbation approximation described in the paper. For the held-out compressed covariance:
Chat^(-s) ~ Chat - w_s S_s
The eigenvalues and eigenvectors are updated using: - deltalambda_j = -w_s v_j^T S_s v_j (eigenvalue shift) - deltav_j = -w_s Sum over k!=j of (v_k^T S_s v_j)/(lambda_j - lambda_k) v_k (eigenvector rotation)
This avoids the O(q^3) eigen-decomposition, requiring only O(q^2r) operations where r is the rank. The approximation is accurate when: 1. Subject weights w_s are small (no single subject dominates) 2. Eigenvalue gaps are large (well-separated components) 3. The perturbation S_s is not aligned with transition regions
When these conditions are violated (detected via condition number or eigenvalue gaps), the function can fall back to full eigen-decomposition.
References
Golub, G. H., & Van Loan, C. F. (2013). Matrix computations (4th ed.). Stewart, G. W., & Sun, J. (1990). Matrix perturbation theory.
Examples
# \donttest{
toy <- dkge_sim_toy(
factors = list(A = list(L = 2), B = list(L = 3)),
active_terms = c("A", "B"), S = 4, P = 20, snr = 5
)
fit <- dkge(toy$B_list, toy$X_list, kernel = toy$K, rank = 2)
#> Warning: Argument 'kernel' is deprecated; use 'K' instead.
c_vec <- c(1, -1, 0, 0, 0)
result <- dkge_analytic_loso(fit, s = 1, contrasts = c_vec)
result$method
#> [1] "fallback"
# }