Iteratively solves for the fixed-effects coefficient vector
beta and the random-effects vector alpha using only the
aggregated sufficient summary, implementing Algorithm 1 of Jalili and
Lin (2025) for the normal linear VCMM. The raw response and design
matrices are not needed: everything reads off stats, which may
come from a single call to compute_sufficient_stats() or from a
streaming accumulator (init_accumulator() plus repeated
accumulate_stats()).
Usage
fit_ss(stats, penalty, control = vcmm_control(), re_cov_state = NULL)
# S3 method for class 'vcmm_fit'
print(x, ...)Arguments
- stats
A
vcmm_ssorvcmm_accumulatorobject containing the aggregated sufficient statistics.- penalty
A symmetric \(p \times p\) penalty matrix from
build_penalty_matrix().- control
A
vcmm_controlobject with fitting options. Passvcmm_control()to use defaults.- re_cov_state
Optional. An internal random-effects covariance state object (NULL for diagonal, or constructed for kronecker via
vcmm()withre_cov = "kronecker"). When NULL, the prior precision is(sigma_eps^2 / sigma_alpha^2) * I_qmatching the diagonal case. Advanced users typically reachre_cov_stateviavcmm()rather than callingfit_ss()directly.- x
A
vcmm_fitobject.- ...
Unused; present for S3 method consistency.
Value
A list of class "vcmm_fit" with elements:
beta: fitted fixed-effects vector, length p.alpha: fitted random-effects vector, length q.sigma_eps: final residual standard deviation.sigma_alpha: final random-effect standard deviation.iterations: number of iterations performed.converged:TRUEif convergence tolerances were met.elapsed_sec: wall-clock fitting time in seconds.n_obs,p,q: data and design dimensions.method: character,"SS".control: thevcmm_controlobject used.call: the matched call.
Details
At each iteration the algorithm solves:
beta-update:
(C + P) beta = b - XtZ %*% alphaalpha-update:
(ZtZ + (sigma_eps^2 / sigma_alpha^2) * I) alpha = Zty - t(XtZ) %*% beta
Both linear systems are solved via invert_matrix(), which
automatically dispatches between solve() and SVD pseudo-inverse
depending on dimension and condition number. Convergence is declared
when the relative change in both beta and alpha falls
below their respective tolerances.
If control$update_variance is TRUE, the residual variance
is re-estimated each iteration from the SS residual sum of squares,
and the random-effect variance is re-estimated as
mean(alpha^2).
References
Jalili, L. and Lin, L.-H. (2025). Scalable and Communication-Efficient Varying Coefficient Mixed-Effects Models.
Examples
set.seed(1)
n <- 200; p <- 4; q <- 3
X <- cbind(1, matrix(rnorm(n * (p - 1)), n, p - 1))
Z <- matrix(rnorm(n * q), n, q)
alpha_true <- rnorm(q, sd = 0.5)
y <- as.vector(
X %*% c(2, 0.5, -0.3, 0.8) + Z %*% alpha_true + rnorm(n, sd = 0.5)
)
# Build sufficient statistics and penalty
stats <- compute_sufficient_stats(y, X, Z)
P <- build_penalty_matrix(n_basis = p - 1, lambda = 0.1)
# Fit with fixed variances
fit <- fit_ss(stats, P,
vcmm_control(sigma_eps = 0.5, sigma_alpha = 0.5))
fit
#> <vcmm_fit> Varying Coefficient Mixed-Effects Model fit
#> method : SS
#> n_obs : 200
#> p (fixed) : 4
#> q (random) : 3
#> RE cov : diag
#> iterations : 5 (converged)
#> sigma_eps : 0.5000
#> sigma_alpha : 0.5000
#> elapsed : <0.001 sec
coef(fit)
#> beta_1 beta_2 beta_3 beta_4
#> 2.0268439 0.5047267 -0.2624521 0.8393673