pub fn lasso(
latents: ArrayView2<'_, f64>,
signal: ArrayView2<'_, f64>,
penalty: f64,
loadings: &mut Array2<f64>,
)Expand description
Sparse loadings for every channel: column c of loadings (latent × channel) minimises
(1/2T)‖x_c − Zᵀa‖² + penalty·‖a‖₁, where latents is Z (latent × sample) and signal
is X (channel × sample). This is scikit-learn’s Lasso(alpha=penalty, fit_intercept=False).
Cyclic coordinate descent on the Gram matrix, warm-started from loadings, one channel per
thread. A channel stops at the first of:
- after sweeps 1, 2, 4, 8, …: the optimality conditions, solved exactly for the current signs, hold
- no coefficient moves by more than 1e-13 of the largest one
- every 32 sweeps: the duality gap is at most 1e-14 of the channel’s mean power
- 1000 sweeps. Nearly collinear latents can need more; a warning then says how many channels stopped early.