annotate toolboxes/alps/ALPS/one_ALPS.m @ 184:8fc38e8df8c6 danieleb

Minor edits
author Daniele Barchiesi <daniele.barchiesi@eecs.qmul.ac.uk>
date Fri, 27 Jan 2012 13:18:50 +0000
parents 0de08f68256b
children
rev   line source
ivan@154 1 function [x_hat, numiter, x_path] = one_ALPS(y, Phi, K, params)
ivan@154 2 % =========================================================================
ivan@154 3 % 1-ALPS(#) algorithm - Beta Version
ivan@154 4 % =========================================================================
ivan@154 5 % Algebraic Pursuit (ALPS) algorithm with 1-memory acceleration.
ivan@154 6 %
ivan@154 7 % Detailed discussion on the algorithm can be found in
ivan@154 8 % [1] "On Accelerated Hard Thresholding Methods for Sparse Approximation", written
ivan@154 9 % by Volkan Cevher, Technical Report, 2011.
ivan@154 10 % =========================================================================
ivan@154 11 % INPUT ARGUMENTS:
ivan@154 12 % y M x 1 undersampled measurement vector.
ivan@154 13 % Phi M x N regression matrix.
ivan@154 14 % K Sparsity of underlying vector x* or desired
ivan@154 15 % sparsity of solution.
ivan@154 16 % params Structure of parameters. These are:
ivan@154 17 %
ivan@154 18 % tol,... Early stopping tolerance. Default value: tol =
ivan@154 19 % 1-e5.
ivan@154 20 % ALPSiters,... Maximum number of algorithm iterations. Default
ivan@154 21 % value: 300.
ivan@154 22 % solveNewtonb,... If solveNewtonb == 1: Corresponds to solving a
ivan@154 23 % Newton system restricted to a sparse support.
ivan@154 24 % It is implemented via conjugate gradients.
ivan@154 25 % If solveNewtonb == 0: Step size selection as described
ivan@154 26 % in eqs. (12) and (13) in [1].
ivan@154 27 % Default value: solveNewtonb = 0.
ivan@154 28 % gradientDescentx,... If gradientDescentx == 1: single gradient
ivan@154 29 % update of x_{i+1} restricted ot its support with
ivan@154 30 % line search. Default value: gradientDescentx =
ivan@154 31 % 1.
ivan@154 32 % solveNewtonx,... If solveNewtonx == 1: Akin to Hard Thresholding Pursuit
ivan@154 33 % (c.f. Simon Foucart, "Hard Thresholding Pursuit,"
ivan@154 34 % preprint, 2010). Default vale: solveNewtonx = 0.
ivan@154 35 % tau,... Variable that controls the momentum in
ivan@154 36 % non-memoryless case. Ignored in memoryless
ivan@154 37 % case. Default value: tau = 1/2.
ivan@154 38 % Special cases:
ivan@154 39 % - tau = 0: momentum step size selection is
ivan@154 40 % driven by the following formulas:
ivan@154 41 % a_1 = 1;
ivan@154 42 % a_{i+1} = (1+\sqrt(1+4a_i^2)/2;
ivan@154 43 % tau = (a_i - 1)/(a_{i+1});
ivan@154 44 % described in [2] "A fast iterative
ivan@154 45 % shrinkage-thresholding algorithm for linear
ivan@154 46 % inverse problems", Beck A., and Teboulle M.
ivan@154 47 % - tau = -1: momentum step size is automatically
ivan@154 48 % optimized in every step.
ivan@154 49 % - tau as a function handle: user defined
ivan@154 50 % behavior of tau momentum term.
ivan@154 51 % mu,... Variable that controls the step size selection.
ivan@154 52 % When mu = 0, step size is computed adaptively
ivan@154 53 % per iteration. Default value: mu = 0.
ivan@154 54 % cg_maxiter,... Maximum iterations for Conjugate-Gradients method.
ivan@154 55 % cg_tol Tolerance variable for Conjugate-Gradients method.
ivan@154 56 % =========================================================================
ivan@154 57 % OUTPUT ARGUMENTS:
ivan@154 58 % x_hat N x 1 recovered K-sparse vector.
ivan@154 59 % numiter Number of iterations executed.
ivan@154 60 % x_path Keeps a series of computed N x 1 K-sparse vectors
ivan@154 61 % until the end of the iterative process.
ivan@154 62 % =========================================================================
ivan@154 63 % 01/04/2011, by Anastasios Kyrillidis. anastasios.kyrillidis@epfl.ch, EPFL.
ivan@154 64 % =========================================================================
ivan@154 65 % cgsolve.m is written by Justin Romberg, Caltech, Oct. 2005.
ivan@154 66 % Email: jrom@acm.caltech.edu
ivan@154 67 % =========================================================================
ivan@154 68 % This work was supported in part by the European Commission under Grant
ivan@154 69 % MIRG-268398 and DARPA KeCoM program #11-DARPA-1055. VC also would like
ivan@154 70 % to acknowledge Rice University for his Faculty Fellowship.
ivan@154 71 % =========================================================================
ivan@154 72
ivan@154 73 [M,N] = size(Phi);
ivan@154 74
ivan@154 75 %% Initialize transpose of measurement matrix
ivan@154 76
ivan@154 77 Phi_t = Phi';
ivan@154 78
ivan@154 79 %% Initialize to zero vector
ivan@154 80 x_cur = zeros(N,1);
ivan@154 81 y_cur = zeros(N,1);
ivan@154 82 Phi_x_cur = zeros(M,1);
ivan@154 83 Y_i = [];
ivan@154 84
ivan@154 85 x_path = zeros(N, params.ALPSiters);
ivan@154 86
ivan@154 87 %% CG params
ivan@154 88 if (params.solveNewtonx == 1 || params.solveNewtonb == 1)
ivan@154 89 cg_verbose = 0;
ivan@154 90 cg_A = Phi_t*Phi;
ivan@154 91 cg_b = Phi_t*y;
ivan@154 92 end;
ivan@154 93
ivan@154 94 %% Determine momentum step size selection strategy
ivan@154 95 fista = 0;
ivan@154 96 optimizeTau = 0;
ivan@154 97 a_prev = 1;
ivan@154 98 function_tau = 0;
ivan@154 99
ivan@154 100 if (isa(params.tau,'float'))
ivan@154 101 function_tau = 0;
ivan@154 102 if (params.tau == 0)
ivan@154 103 fista = 1;
ivan@154 104 optimizeTau = 0;
ivan@154 105 elseif (params.tau == -1)
ivan@154 106 optimizeTau = 1;
ivan@154 107 fista = 0;
ivan@154 108 end;
ivan@154 109 elseif (isa(params.tau, 'function_handle'))
ivan@154 110 function_tau = 1;
ivan@154 111 end;
ivan@154 112
ivan@154 113 %% Determine step size selection strategy
ivan@154 114 function_mu = 0;
ivan@154 115 adaptive_mu = 0;
ivan@154 116
ivan@154 117 if (isa(params.mu,'float'))
ivan@154 118 function_mu = 0;
ivan@154 119 if (params.mu == 0)
ivan@154 120 adaptive_mu = 1;
ivan@154 121 else
ivan@154 122 adaptive_mu = 0;
ivan@154 123 end;
ivan@154 124 elseif (isa(params.mu,'function_handle'))
ivan@154 125 function_mu = 1;
ivan@154 126 end;
ivan@154 127
ivan@154 128 %% Help variables
ivan@154 129 complementary_Yi = ones(N,1);
ivan@154 130
ivan@154 131 i = 1;
ivan@154 132 %% 1-ALPS(#)
ivan@154 133 while (i <= params.ALPSiters)
ivan@154 134 x_path(:,i) = x_cur;
ivan@154 135 x_prev = x_cur;
ivan@154 136
ivan@154 137 % Compute the residual
ivan@154 138 if (i == 1)
ivan@154 139 res = y;
ivan@154 140 % Compute the derivative
ivan@154 141 der = Phi_t*res;
ivan@154 142 else
ivan@154 143 % Compute the derivative
ivan@154 144 if (optimizeTau)
ivan@154 145 res = y - Phi_x_cur - params.tau*Phi_diff;
ivan@154 146 else
ivan@154 147 res = y - Phi(:,Y_i)*y_cur(Y_i);
ivan@154 148 end;
ivan@154 149 der = Phi_t*res;
ivan@154 150 end;
ivan@154 151
ivan@154 152 Phi_x_prev = Phi_x_cur;
ivan@154 153
ivan@154 154 % Determine S_i set via eq. (11) (change of variable from x_i to y_i)
ivan@154 155 complementary_Yi(Y_i) = 0;
ivan@154 156 [tmpArg, ind_der] = sort(abs(der).*complementary_Yi, 'descend');
ivan@154 157 complementary_Yi(Y_i) = 1;
ivan@154 158 S_i = [Y_i; ind_der(1:K)];
ivan@154 159
ivan@154 160 ider = der(S_i);
ivan@154 161 if (params.solveNewtonb == 1)
ivan@154 162 % Compute least squares solution of the system A*y = (A*A)x using CG
ivan@154 163 if (params.useCG == 1)
ivan@154 164 [b, tmpArg, tmpArg] = cgsolve(cg_A(S_i, S_i), cg_b(S_i), params.cg_tol, params.cg_maxiter, cg_verbose);
ivan@154 165 else
ivan@154 166 b = cg_A(S_i,S_i)\cg_b(S_i);
ivan@154 167 end;
ivan@154 168 else
ivan@154 169 % Step size selection via eq. (12) and eq. (13) (change of variable from x_i to y_i)
ivan@154 170 if (adaptive_mu)
ivan@154 171 Pder = Phi(:,S_i)*ider;
ivan@154 172 mu_bar = ider'*ider/(Pder'*Pder);
ivan@154 173 b = y_cur(S_i) + (mu_bar)*ider;
ivan@154 174 elseif (function_mu)
ivan@154 175 b = y_cur(S_i) + params.mu(i)*ider;
ivan@154 176 else b = y_cur(S_i) + params.mu*ider;
ivan@154 177 end;
ivan@154 178 end;
ivan@154 179
ivan@154 180 % Hard-threshold b and compute X_{i+1}
ivan@154 181 [tmpArg, ind_b] = sort(abs(b), 'descend');
ivan@154 182 x_cur = zeros(N,1);
ivan@154 183 x_cur(S_i(ind_b(1:K))) = b(ind_b(1:K));
ivan@154 184 X_i = S_i(ind_b(1:K));
ivan@154 185
ivan@154 186 if (params.gradientDescentx == 1)
ivan@154 187 % Calculate gradient of estimated vector x_cur
ivan@154 188 Phi_x_cur = Phi(:,X_i)*x_cur(X_i);
ivan@154 189 res = y - Phi_x_cur;
ivan@154 190 der = Phi_t*res;
ivan@154 191 ider = der(X_i);
ivan@154 192
ivan@154 193 if (adaptive_mu)
ivan@154 194 Pder = Phi(:,X_i)*ider;
ivan@154 195 mu_bar = ider'*ider/(Pder'*Pder);
ivan@154 196 x_cur(X_i) = x_cur(X_i) + mu_bar*ider;
ivan@154 197 elseif (function_mu)
ivan@154 198 x_cur(X_i) = x_cur(X_i) + params.mu(i)*ider;
ivan@154 199 else x_cur(X_i) = x_cur(X_i) + params.mu*ider;
ivan@154 200 end;
ivan@154 201 elseif (params.solveNewtonx == 1)
ivan@154 202 % Similar to HTP
ivan@154 203 if (params.useCG == 1)
ivan@154 204 [v, tmpArg, tmpArg] = cgsolve(cg_A(X_i, X_i), cg_b(X_i), params.cg_tol, params.cg_maxiter, cg_verbose);
ivan@154 205 else
ivan@154 206 v = cg_A(X_i, X_i)\cg_b(X_i);
ivan@154 207 end;
ivan@154 208 x_cur(X_i) = v;
ivan@154 209 end;
ivan@154 210
ivan@154 211 if (~function_tau) % If tau is not a function handle...
ivan@154 212 if (fista) % Fista configuration
ivan@154 213 a_cur = (1 + sqrt(1 + 4*a_prev^2))/2;
ivan@154 214 params.tau = (a_prev - 1)/a_cur;
ivan@154 215 a_prev = a_cur;
ivan@154 216 elseif (optimizeTau) % Compute optimized tau
ivan@154 217
ivan@154 218 % tau = argmin ||u - Phi*y_{i+1}||
ivan@154 219 % = <res, Phi*(x_cur - x_prev)>/||Phi*(x_cur - x_prev)||^2
ivan@154 220
ivan@154 221 Phi_x_cur = Phi(:,X_i)*x_cur(X_i);
ivan@154 222 res = y - Phi_x_cur;
ivan@154 223 if (i == 1)
ivan@154 224 Phi_diff = Phi_x_cur;
ivan@154 225 else
ivan@154 226 Phi_diff = Phi_x_cur - Phi_x_prev;
ivan@154 227 end;
ivan@154 228 params.tau = res'*Phi_diff/(Phi_diff'*Phi_diff);
ivan@154 229 end;
ivan@154 230
ivan@154 231 y_cur = x_cur + params.tau*(x_cur - x_prev);
ivan@154 232 Y_i = find(ne(y_cur, 0));
ivan@154 233 else
ivan@154 234 y_cur = x_cur + params.tau(i)*(x_cur - x_prev);
ivan@154 235 Y_i = find(ne(y_cur, 0));
ivan@154 236 end;
ivan@154 237
ivan@154 238 % Test stopping criterion
ivan@154 239 if (i > 1) && (norm(x_cur - x_prev) < params.tol*norm(x_cur))
ivan@154 240 break;
ivan@154 241 end;
ivan@154 242 i = i + 1;
ivan@154 243 end;
ivan@154 244
ivan@154 245 x_hat = x_cur;
ivan@154 246 numiter= i;
ivan@154 247
ivan@154 248 if (i > params.ALPSiters)
ivan@154 249 x_path = x_path(:,1:numiter-1);
ivan@154 250 else
ivan@154 251 x_path = x_path(:,1:numiter);
ivan@154 252 end;