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