annotate matlab/GAP/GAP.m @ 66:ee10ffb60428

Implemented projection on an ellipsoid and modified SL0 accordingly.
author Nic Cleju <nikcleju@gmail.com>
date Mon, 23 Apr 2012 10:55:49 +0300
parents ef63b89b375a
children
rev   line source
nikcleju@17 1 function [xhat, Lambdahat] = GAP(y, M, MH, Omega, OmegaH, params, xinit)
nikcleju@17 2
nikcleju@17 3 %%
nikcleju@17 4 % [xhat, Lambdahat] = GAP(y, M, MH, Omega, OmegaH, params, xinit)
nikcleju@17 5 %
nikcleju@17 6 % Greedy Analysis Pursuit Algorithm
nikcleju@17 7 % This aims to find an approximate (sometimes exact) solution of
nikcleju@17 8 % xhat = argmin || Omega * x ||_0 subject to || y - M * x ||_2 <= epsilon.
nikcleju@17 9 %
nikcleju@17 10 % Outputs:
nikcleju@17 11 % xhat : estimate of the target cosparse vector x0.
nikcleju@17 12 % Lambdahat : estimate of the cosupport of x0.
nikcleju@17 13 %
nikcleju@17 14 % Inputs:
nikcleju@17 15 % y : observation/measurement vector of a target cosparse solution x0,
nikcleju@17 16 % given by relation y = M * x0 + noise.
nikcleju@17 17 % M : measurement matrix. This should be given either as a matrix or as a function handle
nikcleju@17 18 % which implements linear transformation.
nikcleju@17 19 % MH : conjugate transpose of M.
nikcleju@17 20 % Omega : analysis operator. Like M, this should be given either as a matrix or as a function
nikcleju@17 21 % handle which implements linear transformation.
nikcleju@17 22 % OmegaH : conjugate transpose of OmegaH.
nikcleju@17 23 % params : parameters that govern the behavior of the algorithm (mostly).
nikcleju@17 24 % params.num_iteration : GAP performs this number of iterations.
nikcleju@17 25 % params.greedy_level : determines how many rows of Omega GAP eliminates at each iteration.
nikcleju@17 26 % if the value is < 1, then the rows to be eliminated are determined by
nikcleju@17 27 % j : |omega_j * xhat| > greedy_level * max_i |omega_i * xhat|.
nikcleju@17 28 % if the value is >= 1, then greedy_level is the number of rows to be
nikcleju@17 29 % eliminated at each iteration.
nikcleju@17 30 % params.stopping_coefficient_size : when the maximum analysis coefficient is smaller than
nikcleju@17 31 % this, GAP terminates.
nikcleju@17 32 % params.l2solver : legitimate values are 'pseudoinverse' or 'cg'. determines which method
nikcleju@17 33 % is used to compute
nikcleju@17 34 % argmin || Omega_Lambdahat * x ||_2 subject to || y - M * x ||_2 <= epsilon.
nikcleju@17 35 % params.l2_accuracy : when l2solver is 'cg', this determines how accurately the above
nikcleju@17 36 % problem is solved.
nikcleju@17 37 % params.noise_level : this corresponds to epsilon above.
nikcleju@17 38 % xinit : initial estimate of x0 that GAP will start with. can be zeros(d, 1).
nikcleju@17 39 %
nikcleju@17 40 % Examples:
nikcleju@17 41 %
nikcleju@17 42 % Not particularly interesting:
nikcleju@17 43 % >> d = 100; p = 110; m = 60;
nikcleju@17 44 % >> M = randn(m, d);
nikcleju@17 45 % >> Omega = randn(p, d);
nikcleju@17 46 % >> y = M * x0 + noise;
nikcleju@17 47 % >> params.num_iteration = 40;
nikcleju@17 48 % >> params.greedy_level = 0.9;
nikcleju@17 49 % >> params.stopping_coefficient_size = 1e-4;
nikcleju@17 50 % >> params.l2solver = 'pseudoinverse';
nikcleju@17 51 % >> [xhat, Lambdahat] = GAP(y, M, M', Omega, Omega', params, zeros(d, 1));
nikcleju@17 52 %
nikcleju@17 53 % Assuming that FourierSampling.m, FourierSamplingH.m, FDAnalysis.m, etc. exist:
nikcleju@17 54 % >> n = 128;
nikcleju@17 55 % >> M = @(t) FourierSampling(t, n);
nikcleju@17 56 % >> MH = @(u) FourierSamplingH(u, n);
nikcleju@17 57 % >> Omega = @(t) FDAnalysis(t, n);
nikcleju@17 58 % >> OmegaH = @(u) FDSynthesis(t, n);
nikcleju@17 59 % >> params.num_iteration = 1000;
nikcleju@17 60 % >> params.greedy_level = 50;
nikcleju@17 61 % >> params.stopping_coefficient_size = 1e-5;
nikcleju@17 62 % >> params.l2solver = 'cg'; % in fact, 'pseudoinverse' does not even make sense.
nikcleju@17 63 % >> [xhat, Lambdahat] = GAP(y, M, MH, Omega, OmegaH, params, zeros(d, 1));
nikcleju@17 64 %
nikcleju@17 65 % Above: FourierSampling and FourierSamplingH are conjugate transpose of each other.
nikcleju@17 66 % FDAnalysis and FDSynthesis are conjugate transpose of each other.
nikcleju@17 67 % These routines are problem specific and need to be implemented by the user.
nikcleju@17 68
nikcleju@17 69 d = length(xinit(:));
nikcleju@17 70
nikcleju@17 71 if strcmp(class(Omega), 'function_handle')
nikcleju@17 72 p = length(Omega(zeros(d,1)));
nikcleju@17 73 else %% Omega is a matrix
nikcleju@17 74 p = size(Omega, 1);
nikcleju@17 75 end
nikcleju@17 76
nikcleju@17 77 iter = 0;
nikcleju@17 78 lagmult = 1e-4;
nikcleju@17 79 Lambdahat = 1:p;
nikcleju@17 80 while iter < params.num_iteration
nikcleju@17 81 iter = iter + 1;
nikcleju@17 82 [xhat, analysis_repr, lagmult] = ArgminOperL2Constrained(y, M, MH, Omega, OmegaH, Lambdahat, xinit, lagmult, params);
nikcleju@17 83 [to_be_removed, maxcoef] = FindRowsToRemove(analysis_repr, params.greedy_level);
nikcleju@17 84 %disp(['** maxcoef=', num2str(maxcoef), ' target=', num2str(params.stopping_coefficient_size), ' rows_remaining=', num2str(length(Lambdahat)), ' lagmult=', num2str(lagmult)]);
nikcleju@17 85 if check_stopping_criteria(xhat, xinit, maxcoef, lagmult, Lambdahat, params)
nikcleju@17 86 break;
nikcleju@17 87 end
nikcleju@17 88 xinit = xhat;
nikcleju@17 89 Lambdahat(to_be_removed) = [];
nikcleju@17 90
nikcleju@17 91 %n = sqrt(d);
nikcleju@17 92 %figure(9);
nikcleju@17 93 %RR = zeros(2*n, n-1);
nikcleju@17 94 %RR(Lambdahat) = 1;
nikcleju@17 95 %XD = ones(n, n);
nikcleju@17 96 %XD(:, 2:end) = XD(:, 2:end) .* RR(1:n, :);
nikcleju@17 97 %XD(:, 1:(end-1)) = XD(:, 1:(end-1)) .* RR(1:n, :);
nikcleju@17 98 %XD(2:end, :) = XD(2:end, :) .* RR((n+1):(2*n), :)';
nikcleju@17 99 %XD(1:(end-1), :) = XD(1:(end-1), :) .* RR((n+1):(2*n), :)';
nikcleju@17 100 %XD = FD2DiagnosisPlot(n, Lambdahat);
nikcleju@17 101 %imshow(XD);
nikcleju@17 102 %figure(10);
nikcleju@17 103 %imshow(reshape(real(xhat), n, n));
nikcleju@17 104 end
nikcleju@17 105 return;
nikcleju@17 106
nikcleju@17 107
nikcleju@17 108 function [to_be_removed, maxcoef] = FindRowsToRemove(analysis_repr, greedy_level)
nikcleju@17 109
nikcleju@17 110 abscoef = abs(analysis_repr(:));
nikcleju@17 111 n = length(abscoef);
nikcleju@17 112 maxcoef = max(abscoef);
nikcleju@17 113 if greedy_level >= 1
nikcleju@17 114 qq = quantile(abscoef, 1-greedy_level/n);
nikcleju@17 115 else
nikcleju@17 116 qq = maxcoef*greedy_level;
nikcleju@17 117 end
nikcleju@17 118
nikcleju@17 119 to_be_removed = find(abscoef >= qq);
nikcleju@17 120 return;
nikcleju@17 121
nikcleju@17 122 function r = check_stopping_criteria(xhat, xinit, maxcoef, lagmult, Lambdahat, params)
nikcleju@17 123
nikcleju@17 124 r = 0;
nikcleju@17 125
nikcleju@17 126 if isfield(params, 'stopping_coefficient_size') && maxcoef < params.stopping_coefficient_size
nikcleju@17 127 r = 1;
nikcleju@17 128 return;
nikcleju@17 129 end
nikcleju@17 130
nikcleju@17 131 if isfield(params, 'stopping_lagrange_multiplier_size') && lagmult > params.stopping_lagrange_multiplier_size
nikcleju@17 132 r = 1;
nikcleju@17 133 return;
nikcleju@17 134 end
nikcleju@17 135
nikcleju@17 136 if isfield(params, 'stopping_relative_solution_change') && norm(xhat-xinit)/norm(xhat) < params.stopping_relative_solution_change
nikcleju@17 137 r = 1;
nikcleju@17 138 return;
nikcleju@17 139 end
nikcleju@17 140
nikcleju@17 141 if isfield(params, 'stopping_cosparsity') && length(Lambdahat) < params.stopping_cosparsity
nikcleju@17 142 r = 1;
nikcleju@17 143 return;
nikcleju@17 144 end