停止条件も含めて計算手順をまとめます。またそれぞれの操作を octave でも書いてみました。
ここで、前回 1A ( = ones (length(A), 1) ) としていた部分を s ( = sign (βj) = sign (cj) ) で置き換えます。それに伴い XA の部分も変更します。こちらの方がすっきりします。
観測データベクトルを y 、説明変数を列に格納した行列を X
X のサイズを m、 n に格納
[m, n] = size(X);
入力データ X、y を基準化及び中心化
y = y - mean(y);
for i = 1:n
Xi = X( : , i);
Xi= Xi - mean(Xi);
Xi = Xi / sqrt( Xi' * Xi);
end
1.初期値設定
停止フラグをリセット
mu = zeros(m, 1); % μ = 0
beta = zeros(n , 1); % β= 0
A = []; % A = φ
stop_flag = false;
2.correlationの更新
c = X' * (y - mu);
相関の絶対値の最大値を更新
A = φ ならその指標を記録
[ hat_c, c_amax_idx_tmp] = max( abs(c) );
if ( length(A) == 0 ),
c_amax_idx = c_amax_idx_tmp;
end
3.アクティブセットを更新
ならそれをアクティブセットに加える。
if c_amax_idx >= 0,
A = [A, c_amax_idx];
end
4.等角ベクトルを更新
XA = X( : , A); % XA
GA = XA' * XA; % gA
invGA = inv(GA);
s = sign( c(A) ); % s
absA = 1 / (s' * invGA * s); % A_A
u = XA * wa; % uA
5.ステップサイズを更新
ここに
a = X' * u;
Ac = setdiff(1 : n, A); % complement of A
for i = 1:length(Ac),
j = Ac(i);
e1 = (hat_C - c(j) ) / (absA - a(j) );
e2 = (hat_C + c(j) ) / (absA + a(j) );
if e1 <= 0., e1 = Inf; end
if e2 <= 0., e2 = Inf; end
gamma_hat_tmp(i) = min(e1, e2);
end
[ gamma_hat, idx ] = min( gamma_hat_tmp );
gamma_hat_idx = Ac(idx);
gamma_tilde_tmp = - beta (A) . / w;
gamma_tilde_tmp( gamma_tilde_tmp <= 0 ) = Inf;
[ gamma_tilde, gamma_tilde_idx ] = min(gamma_tilde_tmp);
if isnan(gamma_tilde),
gamma_tilde = Inf;
end
なら
なら
if gamma_hat < gamma_tilde,
step_size = gamma_hat;
else
step_size = gamma_tilde;
end
6.βを更新
beta_new = zeros(n, 1);
beta_new(A) = beta(A) + step_size * w;
7.βのL1ノルムと閾値 t の比較
ならステップサイズを以下に更新
βを以下の線形補完値に更新しなおし、停止フラグを立てる。
nrm1_prev = sum( abs( beta ) );
nrm1_cur = sum( abs( beta_new ) );
if nrm1_prev <= t && t <= nrm1_cur,
step_size = absA * (t - nrm1_prev);
beta_new(A) = beta(A) + step_size * w;
stop_flag = true;
end
8.β、μを更新
β = β'
beta = beta_new;
mu = mu + step_size * u;
9.ストップフラグが立っていなければアクティブセットを更新
なら
に対応する指標 j について
とおく。
なら
に対応する指標をアクティブセットから除く。
if ~stop_flag,
if gamma_hat < gamma_tilde,
c_amax_idx = gamma_hat_idx;
else
A( gamma_tilde_idx ) = [];
c_amax_idx = -1;
end
end
以下 length(A) < n && !stop_flag の間 2~9 を繰り返す。