annotate scripts/study_analysis_rec_approx.m @ 29:bc2a96a03b0a

2011 nov 10. Rewrote a single ABSapprox file, reorganized functions
author nikcleju
date Thu, 10 Nov 2011 18:49:38 +0000
parents edb5a287e0bb
children
rev   line source
nikcleju@10 1 % File: study_analysis_rec_algos
nikcleju@10 2 % Run experiment to prove that our approx. ABS approach really converges to
nikcleju@10 3 % the anaysis solution as lambda -> infty
nikcleju@10 4 % For this, we need to generate signals that, provably, yield bad results
nikcleju@10 5 % with synthesis recovery, and good results with analysis recovery
nikcleju@10 6 % To do this we choose, N >> d, small l, and m close to d
nikcleju@10 7
nikcleju@10 8 clear all
nikcleju@10 9 close all
nikcleju@10 10
nikcleju@10 11 % =================================
nikcleju@10 12 % Set up experiment parameters
nikcleju@10 13 %==================================
nikcleju@10 14 % Which form factor, delta and rho we want
nikcleju@10 15 sigma = 2;
nikcleju@10 16 %delta = 0.995;
nikcleju@10 17 %rho = 0.7;
nikcleju@10 18 %delta = 0.8;
nikcleju@10 19 %rho = 0.15;
nikcleju@10 20 delta = 0.5;
nikcleju@10 21 rho = 0.05;
nikcleju@10 22
nikcleju@10 23 % Number of vectors to generate each time
nikcleju@10 24 numvects = 10;
nikcleju@10 25
nikcleju@10 26 % Add noise
nikcleju@10 27 % This is norm(signal)/norm(noise), so power, not energy
nikcleju@10 28 SNRdb = 20;
nikcleju@10 29 %epsextrafactor = 2
nikcleju@10 30
nikcleju@10 31 % =================================
nikcleju@10 32 % Processing the parameters
nikcleju@10 33 %==================================
nikcleju@10 34
nikcleju@10 35 % Compute noiselevel from db
nikcleju@10 36 noiselevel = 1 / (10^(SNRdb/10));
nikcleju@10 37
nikcleju@10 38 % Set up parameter structure
nikcleju@10 39 % and generate data X as well
nikcleju@10 40 d = 50;
nikcleju@10 41 p = round(sigma*d);
nikcleju@10 42 m = round(delta*d);
nikcleju@10 43 l = round(d - rho*m);
nikcleju@10 44
nikcleju@10 45 % Generate Omega and data based on parameters
nikcleju@10 46 Omega = Generate_Analysis_Operator(d, p);
nikcleju@10 47 %Make Omega more coherent
nikcleju@10 48 [U, S, V] = svd(Omega);
nikcleju@10 49 %Sdnew = diag(S) ./ (1:numel(diag(S)))';
nikcleju@10 50 Sdnew = diag(S) .* (1:numel(diag(S)))'; % Make D coherent, not Omega!
nikcleju@10 51 Snew = [diag(Sdnew); zeros(size(S,1) - size(S,2), size(S,2))];
nikcleju@10 52 Omega = U * Snew * V';
nikcleju@10 53 [x0,y,M,Lambda, realnoise] = Generate_Data_Known_Omega(Omega, d,p,m,l,noiselevel, numvects,'l0');
nikcleju@10 54
nikcleju@10 55 datafilename = 'mat/data_SNR20';
nikcleju@10 56 save(datafilename);
nikcleju@10 57 %load mat/data_SNR20
nikcleju@10 58
nikcleju@10 59 % Values of lambda
nikcleju@10 60 %lambdas = sqrt([1e-10 1e-8 1e-6 1e-4 1e-2 1 100 1e4 1e6 1e8 1e10]);
nikcleju@10 61 lambdas = [0 10.^linspace(-5, 4, 10)];
nikcleju@10 62 %lambdas = 1000
nikcleju@10 63 %lambdas = sqrt([0 1 10000]);
nikcleju@10 64
nikcleju@10 65 % Algorithm identifiers
nikcleju@10 66 algonone = [];
nikcleju@10 67 ompk = 1;
nikcleju@10 68 ompeps = 2;
nikcleju@10 69 tst = 3;
nikcleju@10 70 bp = 4;
nikcleju@10 71 gap = 5;
nikcleju@10 72 nesta = 6;
nikcleju@10 73 sl0 = 7;
nikcleju@10 74 yall1 = 8;
nikcleju@10 75 spgl1 = 9;
nikcleju@10 76 nestasynth = 10;
nikcleju@10 77 numallalgos = 10;
nikcleju@10 78 algoname{ompk} = 'ABS OMPk';
nikcleju@10 79 algoname{ompeps} = 'ABS OMPeps';
nikcleju@10 80 algoname{tst} = 'ABS TST';
nikcleju@10 81 algoname{bp} = 'ABS BP';
nikcleju@10 82 algoname{gap} = 'GAP';
nikcleju@10 83 algoname{nesta} = 'NESTA Analysis';
nikcleju@10 84 algoname{sl0} = 'ABS SL0';
nikcleju@10 85 algoname{yall1} = 'ABS YALL1';
nikcleju@10 86 algoname{spgl1} = 'ABS SPGL1';
nikcleju@10 87 algoname{nestasynth} = 'NESTA Synth';
nikcleju@10 88
nikcleju@10 89 % What algos to run
nikcleju@10 90 %algos = [gap, ompk, ompeps, tst, bp, sl0, yall1];
nikcleju@10 91 %algos = [gap, ompk, ompeps, tst, bp];
nikcleju@10 92 algos = [gap, sl0];
nikcleju@10 93 numalgos = numel(algos);
nikcleju@10 94
nikcleju@10 95 % Save mat file?
nikcleju@10 96 do_save_mat = 0;
nikcleju@10 97 matfilename = 'mat/approx_d50_sigma2_SNR20db_Dcoh';
nikcleju@10 98
nikcleju@10 99 % Save figures?
nikcleju@10 100 do_save_figs = 0;
nikcleju@10 101 figfilename = 'figs/approx_d50_sigma2_SNR20db_Dcoh';
nikcleju@10 102
nikcleju@10 103 % Show progressbar ? (not recommended when running on parallel threads)
nikcleju@10 104 do_progressbar = 0;
nikcleju@10 105 if do_progressbar
nikcleju@10 106 progressbar('Total', 'Current parameters');
nikcleju@10 107 end
nikcleju@10 108
nikcleju@10 109 % Init times
nikcleju@10 110 for i = 1:numalgos
nikcleju@10 111 elapsed(algos(i)) = 0;
nikcleju@10 112 end
nikcleju@10 113
nikcleju@10 114 % Init results structure
nikcleju@10 115 results = [];
nikcleju@10 116
nikcleju@10 117
nikcleju@10 118 % ========
nikcleju@10 119 % Run
nikcleju@10 120 % ========
nikcleju@10 121
nikcleju@10 122 % Run GAP and NESTA first
nikcleju@10 123 if any(algos == gap)
nikcleju@10 124 for iy = 1:size(y,2)
nikcleju@10 125 a = gap;
nikcleju@10 126 % Compute epsilon
nikcleju@10 127 %epsilon = epsextrafactor * noiselevel * norm(y(:,iy));
nikcleju@10 128 epsilon = 1.1 * norm(realnoise(:,iy));
nikcleju@10 129 %
nikcleju@10 130 gapparams = [];
nikcleju@10 131 gapparams.num_iteration = 1000;
nikcleju@10 132 gapparams.greedy_level = 0.9;
nikcleju@10 133 gapparams.stopping_coefficient_size = 1e-4;
nikcleju@10 134 gapparams.l2solver = 'pseudoinverse';
nikcleju@10 135 %gapparams.noise_level = noiselevel;
nikcleju@10 136 gapparams.noise_level = epsilon;
nikcleju@10 137 timer(a) = tic;
nikcleju@10 138 xrec{a}(:,iy) = GAP(y(:,iy), M, M', Omega, Omega', gapparams, zeros(d,1));
nikcleju@10 139 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 140 %
nikcleju@10 141 err{a}(iy) = norm(x0(:,iy) - xrec{a}(:,iy));
nikcleju@10 142 relerr{a}(iy) = err{a}(iy) / norm(x0(:,iy));
nikcleju@10 143 end
nikcleju@10 144 disp([ algoname{a} ': avg relative error = ' num2str(mean(relerr{a}))]);
nikcleju@10 145 end
nikcleju@10 146 if any(algos == nesta)
nikcleju@10 147 for iy = 1:size(y,2)
nikcleju@10 148 a = nesta;
nikcleju@10 149 % Compute epsilon
nikcleju@10 150 %epsilon = epsextrafactor * noiselevel * norm(y(:,iy));
nikcleju@10 151 epsilon = 1.1 * norm(realnoise(:,iy));
nikcleju@10 152 %
nikcleju@10 153 try
nikcleju@10 154 timer(a) = tic;
nikcleju@10 155 %xrec{a}(:,iy) = do_nesta_DemoNonProjector(x0(:,iy), M, Omega', 0);
nikcleju@10 156
nikcleju@10 157 % Common heuristic: delta = sqrt(m + 2*sqrt(2*m))*sigma ?????????
nikcleju@10 158 [U,S,V] = svd(M,'econ');
nikcleju@10 159 opts.U = Omega;
nikcleju@10 160 opts.Ut = Omega';
nikcleju@10 161 opts.USV.U=U;
nikcleju@10 162 opts.USV.S=S;
nikcleju@10 163 opts.USV.V=V;
nikcleju@10 164 opts.TolVar = 1e-5;
nikcleju@10 165 opts.Verbose = 0;
nikcleju@10 166 xrec{a}(:,iy) = NESTA(M, [], y(:,iy), 1e-3, epsilon, opts);
nikcleju@10 167 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 168 catch err
nikcleju@10 169 disp('*****ERROR: NESTA throwed error *****');
nikcleju@10 170 xrec{a}(:,iy) = zeros(size(x0(:,iy)));
nikcleju@10 171 end
nikcleju@10 172 %
nikcleju@10 173 err{a}(iy) = norm(x0(:,iy) - xrec{a}(:,iy));
nikcleju@10 174 relerr{a}(iy) = err{a}(iy) / norm(x0(:,iy));
nikcleju@10 175 end
nikcleju@10 176 disp([ algoname{a} ': avg relative error = ' num2str(mean(relerr{a}))]);
nikcleju@10 177 end
nikcleju@10 178
nikcleju@10 179 for i = 1:numel(algos)
nikcleju@10 180 if algos(i) == gap
nikcleju@10 181 continue;
nikcleju@10 182 end
nikcleju@10 183 prevgamma{algos(i)} = zeros(p, numvects);
nikcleju@10 184 end
nikcleju@10 185
nikcleju@10 186 % Run ABS algorithms (lambda-dependent)
nikcleju@10 187 for iparam = 1:numel(lambdas)
nikcleju@10 188
nikcleju@10 189 % Read current parameters
nikcleju@10 190 lambda = lambdas(iparam);
nikcleju@10 191
nikcleju@10 192 % Init stuff
nikcleju@10 193 for i = 1:numel(algos)
nikcleju@10 194 if algos(i) == gap || algos(i) == nesta
nikcleju@10 195 continue;
nikcleju@10 196 end
nikcleju@10 197 xrec{algos(i)} = zeros(d, numvects);
nikcleju@10 198 end
nikcleju@10 199 %
nikcleju@10 200 for i = 1:numel(algos)
nikcleju@10 201 if algos(i) == gap || algos(i) == nesta
nikcleju@10 202 continue;
nikcleju@10 203 end
nikcleju@10 204 err{algos(i)} = zeros(numvects,1);
nikcleju@10 205 relerr{algos(i)} = zeros(numvects,1);
nikcleju@10 206 end
nikcleju@10 207
nikcleju@10 208 % For every generated signal do
nikcleju@10 209 for iy = 1:size(y,2)
nikcleju@10 210
nikcleju@10 211 % Compute epsilon
nikcleju@10 212 %epsilon = epsextrafactor * noiselevel * norm(y(:,iy));
nikcleju@10 213 epsilon = 1.1 * norm(realnoise(:,iy));
nikcleju@10 214
nikcleju@10 215 %--------------------------------
nikcleju@10 216 % Reconstruct (and measure delay), Compute reconstruction error
nikcleju@10 217 %--------------------------------
nikcleju@10 218 for i = 1:numel(algos)
nikcleju@10 219 a = algos(i);
nikcleju@10 220 if a == gap || a == nesta
nikcleju@10 221 continue
nikcleju@10 222 end
nikcleju@10 223 if a == ompk
nikcleju@10 224 timer(a) = tic;
nikcleju@10 225 xrec{a}(:,iy) = ABS_OMPk_approx(y(:,iy), Omega, M, p-l, lambda);
nikcleju@10 226 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 227 elseif a == ompeps
nikcleju@10 228 timer(a) = tic;
nikcleju@10 229 xrec{a}(:,iy) = ABS_OMPeps_approx(y(:,iy), Omega, M, epsilon, lambda, Omega * x0(:,iy));
nikcleju@10 230 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 231 elseif a == tst
nikcleju@10 232 timer(a) = tic;
nikcleju@10 233 xrec{a}(:,iy) = ABS_TST_approx(y(:,iy), Omega, M, epsilon, lambda, Omega * x0(:,iy));
nikcleju@10 234 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 235 elseif a == bp
nikcleju@10 236 timer(a) = tic;
nikcleju@10 237 [xrec{a}(:,iy), prevgamma{a}(:,iy)] = ABS_BP_approx(y(:,iy), Omega, M, epsilon, lambda, prevgamma{a}(:,iy), Omega * x0(:,iy));
nikcleju@10 238 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 239 elseif a == yall1
nikcleju@10 240 timer(a) = tic;
nikcleju@10 241 xrec{a}(:,iy) = ABS_YALL1_approx(y(:,iy), Omega, M, epsilon, lambda, Omega * x0(:,iy));
nikcleju@10 242 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 243 % elseif a == gap
nikcleju@10 244 % gapparams = [];
nikcleju@10 245 % gapparams.num_iteration = 40;
nikcleju@10 246 % gapparams.greedy_level = 0.9;
nikcleju@10 247 % gapparams.stopping_coefficient_size = 1e-4;
nikcleju@10 248 % gapparams.l2solver = 'pseudoinverse';
nikcleju@10 249 % %gapparams.noise_level = noiselevel;
nikcleju@10 250 % gapparams.noise_level = epsilon;
nikcleju@10 251 % timer(a) = tic;
nikcleju@10 252 % xrec{a}(:,iy) = GAP(y(:,iy), M, M', Omega, Omega', gapparams, zeros(d,1));
nikcleju@10 253 % elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 254 % elseif a == nesta
nikcleju@10 255 % try
nikcleju@10 256 % timer(a) = tic;
nikcleju@10 257 % %xrec{a}(:,iy) = do_nesta_DemoNonProjector(x0(:,iy), M, Omega', 0);
nikcleju@10 258 %
nikcleju@10 259 % % Common heuristic: delta = sqrt(m + 2*sqrt(2*m))*sigma ?????????
nikcleju@10 260 % [U,S,V] = svd(M,'econ');
nikcleju@10 261 % opts.U = Omega;
nikcleju@10 262 % opts.Ut = Omega';
nikcleju@10 263 % opts.USV.U=U;
nikcleju@10 264 % opts.USV.S=S;
nikcleju@10 265 % opts.USV.V=V;
nikcleju@10 266 % opts.TolVar = 1e-5;
nikcleju@10 267 % opts.Verbose = 0;
nikcleju@10 268 % xrec{a}(:,iy) = NESTA(M, [], y(:,iy), 1e-3, epsilon, opts);
nikcleju@10 269 % elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 270 % catch err
nikcleju@10 271 % disp('*****ERROR: NESTA throwed error *****');
nikcleju@10 272 % xrec{a}(:,iy) = zeros(size(x0(:,iy)));
nikcleju@10 273 % end
nikcleju@10 274 elseif a == sl0
nikcleju@10 275 timer(a) = tic;
nikcleju@10 276 xrec{a}(:,iy) = ABS_SL0_approx(y(:,iy), Omega, M, epsilon, lambda);
nikcleju@10 277 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 278 elseif a == spgl1
nikcleju@10 279 timer(a) = tic;
nikcleju@10 280 xrec{a}(:,iy) = ABS_SPGL1_approx(y(:,iy), Omega, M, epsilon, lambda, Omega * xrec{bp}(:,iy));
nikcleju@10 281 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 282 elseif a == nestasynth
nikcleju@10 283 timer(a) = tic;
nikcleju@10 284 xrec{a}(:,iy) = ABS_NESTAsynth_approx(y(:,iy), Omega, M, epsilon, lambda, Omega * xrec{bp}(:,iy));
nikcleju@10 285 elapsed(a) = elapsed(a) + toc(timer(a));
nikcleju@10 286 else
nikcleju@10 287 %error('No such algorithm!');
nikcleju@10 288 end
nikcleju@10 289 %
nikcleju@10 290 % Compare to GAP instead!
nikcleju@10 291 %x0(:,iy) = xrec{gap}(:,iy);
nikcleju@10 292 %
nikcleju@10 293 err{a}(iy) = norm(x0(:,iy) - xrec{a}(:,iy));
nikcleju@10 294 relerr{a}(iy) = err{a}(iy) / norm(x0(:,iy));
nikcleju@10 295 end
nikcleju@10 296
nikcleju@10 297 % Update progressbar
nikcleju@10 298 % if do_progressbar
nikcleju@10 299 % %frac2 = iy/numvects;
nikcleju@10 300 % %frac1 = ((iparam-1) + frac2) / count;
nikcleju@10 301 % if norm(frac2 - 1) < 1e-6
nikcleju@10 302 % frac2 = 0;
nikcleju@10 303 % end
nikcleju@10 304 % frac2 = frac2 + incr2;
nikcleju@10 305 % frac1 = frac1 + incr1;
nikcleju@10 306 % progressbar(frac1, frac2);
nikcleju@10 307 % end
nikcleju@10 308 end
nikcleju@10 309
nikcleju@10 310 %--------------------------------
nikcleju@10 311 % Save results in big stucture & display
nikcleju@10 312 %--------------------------------
nikcleju@10 313 % Save reconstructed signals
nikcleju@10 314 % Save rel & abs errors
nikcleju@10 315 % Display error
nikcleju@10 316 results(iparam).xrec = xrec;
nikcleju@10 317 results(iparam).err = err;
nikcleju@10 318 results(iparam).relerr = relerr;
nikcleju@10 319 %
nikcleju@10 320 %disp(['Simulation no. ' num2str(iparam)]);
nikcleju@10 321 disp(['Lambda = ' num2str(lambda) ':']);
nikcleju@10 322 for i = 1:numalgos
nikcleju@10 323 a = algos(i);
nikcleju@10 324 if a == gap || a == nesta
nikcleju@10 325 continue
nikcleju@10 326 end
nikcleju@10 327 disp([ algoname{a} ': avg relative error = ' num2str(mean(relerr{a}))]);
nikcleju@10 328 end
nikcleju@10 329 end
nikcleju@10 330
nikcleju@10 331 % =================================
nikcleju@10 332 % Save
nikcleju@10 333 % =================================
nikcleju@10 334 if do_save_mat
nikcleju@10 335 save(matfilename);
nikcleju@10 336 disp(['Saved to ' matfilename]);
nikcleju@10 337 end
nikcleju@10 338
nikcleju@10 339 % =================================
nikcleju@10 340 % Plot
nikcleju@10 341 % =================================
nikcleju@10 342 toplot = zeros(numel(lambdas), numalgos);
nikcleju@10 343
nikcleju@10 344 relerrs = {results.relerr};
nikcleju@10 345 for i = 1:numalgos
nikcleju@10 346 for j = 1:numel(lambdas)
nikcleju@10 347 toplot(j,i) = mean(relerrs{j}{algos(i)});
nikcleju@10 348 end
nikcleju@10 349 end
nikcleju@10 350
nikcleju@10 351 %h = plot(toplot);
nikcleju@10 352 h = semilogx(lambdas, toplot);
nikcleju@10 353 legend(algoname{algos})
nikcleju@10 354 xlabel('Lambda')
nikcleju@10 355 ylabel('Average reconstruction error')
nikcleju@10 356 title('Reconstruction error with different algorithms')
nikcleju@10 357
nikcleju@10 358 if (do_save_figs)
nikcleju@10 359 saveas(gcf, [figfilename '.fig']);
nikcleju@10 360 saveas(gcf, [figfilename '.png']);
nikcleju@10 361 saveTightFigure(gcf, [figfilename '.pdf']);
nikcleju@10 362 end
nikcleju@10 363