├── DCATL1_RL_sparsity.m ├── DCA_TL1.m ├── DCA_TL1_sub.m ├── README.md ├── Tools ├── Comp_coherentdic.m ├── coherentdic.m ├── frac_norm.m ├── level lines │ ├── difference.m │ └── level_lines.m ├── level_lines.m ├── mucohere_matrix.m ├── norm0.m ├── randsample_separated.m ├── test_unif_ball.m ├── unif_ball.m └── unitnorm.m ├── choice_of_a.m ├── choice_of_a.mat ├── combi1.mat ├── compare_test.m ├── muco.mat ├── shrink.m ├── test_3Nmatrix.m ├── test_DCA.m └── test_TIME.m /DCATL1_RL_sparsity.m: -------------------------------------------------------------------------------- 1 | function z = DCATL1_RL_sparsity(l) 2 | % Over-sampled DCT matrix 3 | % s: sparsity 4 | % F: RL 5 | % l: interger, such that separation length = l*F 6 | 7 | N = 1024 ; % # of columns 8 | M = 64 ; % # of rows 9 | thresh = 1e-3; % standard for success 10 | testnum = 10; 11 | 12 | F = 10; 13 | 14 | k_seq = 5:3:20; 15 | len = length(k_seq); 16 | 17 | 18 | succ = zeros(1,len); 19 | 20 | 21 | % coefficient for l1-l2 22 | pm.gam = 1e-6; 23 | pm.C = 1e-9; 24 | pm.ep = 1e-6; 25 | pm.maxit = 5000; 26 | pm.maxoit = 20; 27 | pm.otol = 1e-8; 28 | pm.tol = 1e-5; 29 | pm.del = pm.gam*10; 30 | 31 | pm.a = 1; 32 | 33 | 34 | for ii = 1:len 35 | ii 36 | k = k_seq(ii); 37 | 38 | for j = 1:testnum 39 | 40 | %% generate matrix A and right hand y 41 | % cosine matrix 42 | A = coherentdic(M,N,F); 43 | supp = randsample_separated(N,k,l*F); 44 | x = zeros(N,1); 45 | xx = randn(k,1); 46 | x(supp) = xx; 47 | y = A*x; 48 | 49 | % normalizing ... 50 | d = 1./sqrt(sum(A.^2,2)); 51 | A = sparse(1:M,1:M,d)*A; 52 | y = d.*y; 53 | 54 | 55 | 56 | %% computing ... 57 | tic; 58 | z1 = DCA_USC(A,y,pm,zeros(N,1)); 59 | time1 = toc; 60 | 61 | err1 = norm(z1-x)/norm(x); 62 | if err1 < thresh 63 | succ(1,ii) = succ(1,ii) + 1; 64 | fprintf('relative error for DCATL1: %4.3e, iteration time: %4.3e \n',err1,time1); 65 | end 66 | 67 | end 68 | end 69 | z = succ 70 | 71 | -------------------------------------------------------------------------------- /DCA_TL1.m: -------------------------------------------------------------------------------- 1 | %-------------------------------------------------------------------------- 2 | % Difference of Convex Functions Methods for 1-D Compressed Sensing Problem. 3 | % 4 | % Solves 5 | % min P_a(x) 6 | % s.t. Ax = b 7 | % 8 | % Reference: "Minimization of Transformed L_1 Penalty: Theory, 9 | % Difference of Convex Function Algorithm, 10 | % and Robust Application in Compressed Sensing." 11 | % Shuai Zhang, Jack Xin 12 | % IEEE transactions on Information Theory, 2014 13 | % Available at: 14 | % http://arxiv.org/abs/1411.5735 15 | % ftp://ftp.math.ucla.edu/pub/camreport/cam14-86.pdf 16 | % 17 | % Author: Shuai Zhang 18 | % Date: Feb 07. 2015 19 | %-------------------------------------------------------------------------- 20 | 21 | % min_x .5||Ax-b||^2 + gam(sum (a+1)|x_i| / (a+|x_i|) ) 22 | % here g(x) = .5||Ax-b||^2 + C||x||^2 + gam* (a+1)/a * ||x||_1 23 | % h(x) = gam*{(a+1)/a *||x||_1 - sum (a+1)|x_i|/(a+|x_i|)} + C||x||^2 24 | % F(x) = g(x) - h(x) 25 | %Input: dictionary A, data b, parameters option and initial value x0 26 | % recommended value 27 | % x0: initial value, better to chosed as zeros vector, see reference 28 | % pm.C 1.0e-9 29 | % pm.del 1.0e-4 30 | % pm.maxoit 1000 31 | % pm.gam 1.0e-5 32 | % pm.tol 1.0e-5 33 | % pm.a 1 34 | %Output: computed coefficients x 35 | 36 | 37 | function x = DCA_TL1(A,b,pm,x0) 38 | 39 | 40 | if ~exist('pm','var'), 41 | pm = []; 42 | end 43 | C = 1.0e-9; 44 | % del = 1.0e-4; 45 | maxoit = 20; 46 | gam = 1.0e-6; 47 | tol = 1.0e-5; 48 | del = gam*10; 49 | a = 1; 50 | if isfield(pm,'C'), C = pm.C; end 51 | if isfield(pm,'del'), del = pm.del; end 52 | if isfield(pm,'maxoit'), maxoit = pm.maxoit; end 53 | if isfield(pm,'gam'), gam = pm.gam; end 54 | if isfield(pm,'tol'), tol = pm.tol; end 55 | if isfield(pm,'a'), a = pm.a; end 56 | 57 | [M,N] = size(A); 58 | x = x0; 59 | p_init = zeros(N,1); 60 | %precompute inverse to be used in inner problem 61 | L = chol( speye(M) + 1/(2*C+del)*(A*A'), 'lower' ); % cholesky factorization 62 | L = sparse(L); 63 | U = sparse(L'); 64 | Atb = A'*b; 65 | 66 | for it = 1:maxoit 67 | if norm(x) < eps 68 | f = -Atb; 69 | else 70 | V = gam*(a+1)/a * sign(x) - gam*sign(x)*(a+1)./( a+abs(x) ) ... 71 | + gam*(a+1)*x./( a+abs(x) ).^2 + 2*C*x; 72 | f = -Atb - V; 73 | end 74 | [x_new,p_init] = DCA_TL1_sub(A,L,U,f,pm,x,p_init); 75 | %tolerance based stopping condition 76 | err = max(abs(x-x_new))/max(max(abs(x_new)),1); 77 | % err = sqrt(sum((x-x_new).^2))/max(sqrt(sum(x.^2)),1) 78 | x = x_new; 79 | if err < tol 80 | disp(['tolerance met after ' num2str(it) ' iterations with a = ' num2str(a)]); 81 | break; 82 | end 83 | end 84 | 85 | if it == maxoit, fprintf('Unconstrained DCATL1 fails ...... \n'); end 86 | 87 | end -------------------------------------------------------------------------------- /DCA_TL1_sub.m: -------------------------------------------------------------------------------- 1 | %-------------------------------------------------------------------------- 2 | % Difference of Convex Functions Methods for 1-D Compressed Sensing Problem. 3 | % 4 | % Solves 5 | % min P_a(x) 6 | % s.t. Ax = b 7 | % 8 | % Reference: "Minimization of Transformed L_1 Penalty: Theory, 9 | % Difference of Convex Function Algorithm, 10 | % and Robust Application in Compressed Sensing." 11 | % Shuai Zhang, Jack Xin 12 | % IEEE transactions on Information Theory, 2014 13 | % Available at: 14 | % http://arxiv.org/abs/1411.5735 15 | % ftp://ftp.math.ucla.edu/pub/camreport/cam14-86.pdf 16 | % 17 | % Author: Shuai Zhang 18 | % Date: Feb 07. 2015 19 | %-------------------------------------------------------------------------- 20 | 21 | function [x,p] = DCA_TL1_sub(A,L,U,f,pm,x_init,p_init) 22 | 23 | if ~exist('pm','var'), 24 | pm = []; 25 | end 26 | C = 1.0e-9; 27 | gam = 1.0e-6; 28 | del = gam*10; 29 | a = 1; 30 | % del = 1.0e-4; 31 | if isfield(pm,'C'), C = pm.C; end 32 | if isfield(pm,'del'), del = pm.del; end 33 | if isfield(pm,'gam'), gam = pm.gam; end 34 | if isfield(pm,'a'), a = pm.a; end 35 | if isfield(pm,'maxit'), maxit = pm.maxit; end 36 | 37 | 38 | %initialize variables for inner problem 39 | p = p_init; 40 | aa = (a + 1)/a; 41 | z = x_init; 42 | N = size(A,2); 43 | %iterate to solve L1 regularized program 44 | maxIter = min(round(2.5*N), maxit); 45 | for i = 1:maxIter 46 | %x update 47 | q = -f + del*(z - p); 48 | x = q/(2*C+del) - (A'*(U\(L\(A*q))))/(2*C+del)^2; 49 | 50 | %z update 51 | z = shrink(x + p,aa*gam/del); 52 | 53 | %p update 54 | p = p + x - z; 55 | 56 | end 57 | 58 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DCATL1 2 | This is the matlab code for the paper: 3 | ## [Minimization of transformed L1 penalty: theory, difference of convex function algorithm, and robust application in compressed sensin](https://link.springer.com/article/10.1007/s10107-018-1236-x). 4 | 5 | Other related works are: 6 | ### [Minimization of Transformed L1 Penalty: Closed Form Representation and Iterative Thresholding Algorithms](https://arxiv.org/abs/1412.5240) 7 | and 8 | ### [Transformed Schatten-1 Iterative Thresholding Algorithms for Low Rank Matrix Completion](https://arxiv.org/abs/1506.04444) with [Matlab code](https://github.com/zsivine/TS1-algorithms). 9 | 10 | 11 | -------------------------------------------------------------------------------- /Tools/Comp_coherentdic.m: -------------------------------------------------------------------------------- 1 | function A = Comp_coherentdic(M,N,F) 2 | % Generate an M x N oversampled partial Fourier matrix A, 3 | % F is the refinement factor, see Fannjiang's paper: 4 | % 'coherence-pattern guided compressive sensing with unresolved grids' 5 | A = zeros(M,N); 6 | r = rand(M,1); 7 | l = 1:N; 8 | for k = 1:M 9 | A(k,:) = sqrt(2/M)*( cos(2*pi*r(k)*(l-1)/F) - i*sin(2*pi*r(k)*(l-1)/F) ); 10 | end 11 | end 12 | 13 | 14 | -------------------------------------------------------------------------------- /Tools/coherentdic.m: -------------------------------------------------------------------------------- 1 | function A = coherentdic(M,N,F) 2 | % Generate an M x N oversampled partial Fourier matrix A, 3 | % F is the refinement factor, see Fannjiang's paper: 4 | % 'coherence-pattern guided compressive sensing with unresolved grids' 5 | A = zeros(M,N); 6 | r = rand(M,1); 7 | l = 1:N; 8 | for k = 1:M 9 | A(k,:) = sqrt(2/M)*cos(2*pi*r(k)*(l-1)/F); 10 | end 11 | end 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Tools/frac_norm.m: -------------------------------------------------------------------------------- 1 | function y = frac_norm(x,p) 2 | % compute fraction norm p for vector x 3 | x = abs(x); 4 | x = x.^p; 5 | y = sum(x); 6 | y = y^(1/p); -------------------------------------------------------------------------------- /Tools/level lines/difference.m: -------------------------------------------------------------------------------- 1 | %% l1-norm, l2-norm 2 | x = -10:.1:10; 3 | [X,Y] = meshgrid(x); 4 | Z1 = abs(X)+abs(Y)-sqrt(X.^2+Y.^2); 5 | Z2 = (abs(X)+abs(Y))./sqrt(X.^2+Y.^2); 6 | figure, 7 | contour(X,Y,Z1), axis square 8 | title('l1-l2') % colorbar 9 | figure, 10 | contour(X,Y,Z2), axis square 11 | title('l1/l2') 12 | % colorbar -------------------------------------------------------------------------------- /Tools/level lines/level_lines.m: -------------------------------------------------------------------------------- 1 | %% level lines for l1 and transformed l1 \rho_a 2 | clear 3 | close all 4 | clc 5 | %% l1-norm 6 | x = -1:.1:1; 7 | [X,Y] = meshgrid(x); 8 | Z1 = abs(X) + abs(Y); 9 | figure 10 | contour(X,Y,Z1), axis([-1 1 -1 1]); 11 | %title('l1 norm') % colorbar 12 | 13 | 14 | %% transformed l1 15 | a = 1; 16 | x = -1:.1:1; 17 | [X,Y] = meshgrid(x); 18 | Z1 = (a+1)*abs(X)./(a+abs(X)) + (a+1)*abs(Y)./(a+abs(Y)) ; 19 | figure 20 | contour(X,Y,Z1), axis([-1 1 -1 1]); 21 | %title('transformed l1 with a = 1') % colorbar 22 | 23 | 24 | a = 100; 25 | x = -1:.1:1; 26 | [X,Y] = meshgrid(x); 27 | Z1 = (a+1)*abs(X)./(a+abs(X)) + (a+1)*abs(Y)./(a+abs(Y)) ; 28 | figure 29 | contour(X,Y,Z1), axis([-1 1 -1 1]); 30 | %title('transformed l1 with a = 100') % colorbar 31 | 32 | 33 | 34 | a = 0.01; 35 | x = -1:.1:1; 36 | [X,Y] = meshgrid(x); 37 | Z1 = (a+1)*abs(X)./(a+abs(X)) + (a+1)*abs(Y)./(a+abs(Y)) ; 38 | figure 39 | contour(X,Y,Z1), axis([-1 1 -1 1]); 40 | %title('transformed l1 with a = 0.01') % colorbar 41 | 42 | 43 | % a = 0.1; 44 | % x = -1:.1:1; 45 | % [X,Y] = meshgrid(x); 46 | % Z1 = (a+1)*abs(X)./(a+abs(X)) + (a+1)*abs(Y)./(a+abs(Y)) ; 47 | % figure 48 | % contour(X,Y,Z1), axis([-1 1 -1 1]); 49 | % title('transformed l1 with a = 0.1') % colorbar 50 | 51 | 52 | -------------------------------------------------------------------------------- /Tools/level_lines.m: -------------------------------------------------------------------------------- 1 | %% level lines for l0 , l1 and transformed l1 \rho_a 2 | lamda = 0.5:0.1:1; 3 | N = length(lamda); 4 | M = 50; 5 | xx = zeros(N+1,2*M+2); 6 | yy = xx; 7 | 8 | %% l1 9 | l = 2/M; 10 | x1 = -1:l:1; 11 | x2 = 1:-l:-1; 12 | y1 = 1-abs(x1); 13 | y2 = abs(x2) - 1; 14 | xx(1,:) = [x1 x2]; yy(1,:) = [y1 y2]; 15 | figure; 16 | plot(xx(1,:),yy(1,:)); 17 | 18 | %% transformed l1 with different parameters 19 | for i = 1:N 20 | L = lamda(i)/(2-lamda(i)); 21 | l = 2*L/M; 22 | x1 = -L:l:L; 23 | x2 = L:-l:-L; 24 | lam = lamda(i) - 2.*abs(x1)./(1+abs(x1)); 25 | y1 = lam./(2-lam); 26 | lam = lamda(i) - 2.*abs(x2)./(1+abs(x2)); 27 | y2 = lam./(lam-2); 28 | xx(i+1,:) = [x1 x2]; yy(i+1,:) = [y1 y2]; 29 | end 30 | 31 | plot(xx(2:end,:)', yy(2:end,:)') 32 | 33 | axis([-1 1 -1 1]); 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Tools/mucohere_matrix.m: -------------------------------------------------------------------------------- 1 | function z = mucohere_matrix(A) 2 | % computer mutual coherence of matrix A 3 | % normlize columns of A 4 | [m,n] = size(A); 5 | for j = 1:n 6 | t = norm(A(:,j),2); 7 | A(:,j) = A(:,j)./t; 8 | end 9 | 10 | mc = A'*A; 11 | mc(eye(n)~=0) = 0; 12 | mc = abs(mc(:)); 13 | z = max(mc); 14 | 15 | 16 | -------------------------------------------------------------------------------- /Tools/norm0.m: -------------------------------------------------------------------------------- 1 | % l0 norm function 2 | function z = norm0(x,option) 3 | if ~exist('option','var'), 4 | option = []; 5 | end 6 | eps = 0; 7 | if isfield(option,'eps'), eps = option.eps; end 8 | 9 | x = abs(x); 10 | x = x > eps; 11 | z = sum(x); 12 | -------------------------------------------------------------------------------- /Tools/randsample_separated.m: -------------------------------------------------------------------------------- 1 | % generate N_dimension vector with sparsity K, the distance of each nonzero 2 | % element is greater than L 3 | function supp = randsample_separated(N,K,L) 4 | supp = randsample(N-L*(K-1),K); 5 | supp = sort(supp); 6 | supp = supp + (0:K-1)'*L; 7 | end -------------------------------------------------------------------------------- /Tools/test_unif_ball.m: -------------------------------------------------------------------------------- 1 | function [succ,mu] = test_unif_ball(M,N,k) 2 | 3 | % test M*N matrix, column vectors are generated uniformly in unit M-d sphere 4 | % matrix A uniformly over the sphere in R^M 5 | % k = sparsity 6 | 7 | test_num = 100; 8 | thresh = 1e-3; 9 | succ = zeros(4,1); 10 | mu = zeros(test_num,1); 11 | 12 | % coefficient for l1-l2 13 | pm.gam = 1e-6; 14 | pm.C = 1e-9; 15 | pm.maxoit = 20; 16 | pm.tol = 1e-5; 17 | pm.del = pm.gam*10; 18 | pm.a = 1; 19 | % coefficient for IRucLq_v 20 | q = 0.5; 21 | lam2 = 1e-6; 22 | 23 | % coefficient for yall1 24 | opyall.tol = 1e-5; 25 | opyall.rho = 1e-5; 26 | opyall.nonorth = 1; 27 | 28 | for i = 1:test_num 29 | 30 | % intialize 31 | A = unif_ball(M,N); 32 | mu(i) = mucohere_matrix(A); 33 | fprintf('The mutual coherence of matrix A is %d \n', mu(i)); 34 | 35 | % separate two nonzeros elements with certain distance ex. N/3 36 | d = round(N/(2*k)); 37 | supp = randsample_separated(N,k,d); 38 | x = zeros(N,1); 39 | x(supp) = sign(randn(k,1)); 40 | y = A*x; 41 | 42 | % solve by different methods 43 | tic; 44 | z1 = DCA_USC(A,y,pm,zeros(N,1)); 45 | time1 = toc; 46 | tic; 47 | [z2,~] = IRucLq_v(A,y,lam2,q); 48 | time2 = toc; 49 | tic; 50 | z3 = DCAunl1_l2(A,y,pm,zeros(N,1)); 51 | time3 = toc; 52 | tic; 53 | z4 = yall1(A,y,opyall); 54 | time4 = toc; 55 | 56 | 57 | 58 | % display error 59 | err1 = norm(z1-x)/norm(x); 60 | if err1 < thresh 61 | succ(1) = succ(1) + 1; 62 | fprintf('relative error for DCATL1: %4.3e, iteration time: %4.3e \n',err1,time1); 63 | end 64 | 65 | err2 = norm(z2-x)/norm(x); 66 | if err2 < thresh 67 | succ(2) = succ(2) + 1; 68 | fprintf('relative error for IRucLq_v: %4.3e, iteration time: %4.3e \n',err2,time2); 69 | end 70 | 71 | err3 = norm(z3-x)/norm(x); 72 | if err3 < thresh 73 | succ(3) = succ(3) + 1; 74 | fprintf('relative error for DCA l1-l2: %4.3e, iteration time: %4.3e \n',err3,time3); 75 | end 76 | 77 | err4 = norm(z4-x)/norm(x); 78 | if err4 < thresh 79 | succ(4) = succ(4) + 1; 80 | fprintf('relative error for yall1: %4.3e, iteration time: %4.3e \n',err4,time4); 81 | end 82 | 83 | % % sparsity 84 | % op_spar.eps = 5e-2; 85 | % s1 = norm0(z1,op_spar); 86 | % fprintf('sparsity difference: %d \n',s1-k ); 87 | % s2 = norm0(z2,op_spar); 88 | % fprintf('sparsity difference: %d \n',abs(s2-k)); 89 | % s3 = norm0(z3,op_spar); 90 | % fprintf('sparsity difference: %d \n',abs(s3-k)); 91 | 92 | 93 | % subplot(2,1,1); 94 | % plot(x,'o'); 95 | % subplot(2,1,2); 96 | % plot(z1,'*'); 97 | % pause; 98 | 99 | end 100 | 101 | succ = succ./test_num; 102 | mu = sum(mu(:))/test_num; 103 | 104 | 105 | -------------------------------------------------------------------------------- /Tools/unif_ball.m: -------------------------------------------------------------------------------- 1 | function A = unif_ball(m,n) 2 | % generate m*n matirx, where column vectors are distributed uniformly on a 3 | % m-dimensional unit ball. 4 | 5 | %% method 1: fail 6 | % % generate spherical coordinates 7 | % theta = rand(m-1,n,'double'); 8 | % theta(1:end-1,:) = theta(1:end-1,:)*pi; 9 | % theta(end,:) = theta(end,:)*2*pi; 10 | % 11 | % z = ones(1,n); 12 | % A = zeros(m,n); 13 | % for i = 1:m-1 14 | % A(i,:) = cos(theta(i,:)).*z; 15 | % z = z.*sin(theta(i,:)); 16 | % end 17 | % A(end,:) = z; 18 | 19 | 20 | 21 | 22 | %% method 2: 23 | % generate n Gaussian random variables x. 24 | % Then the distribution of unitized vectors is uniform over the surface $S^(n-1)$ 25 | x = randn(m,n); 26 | A = bsxfun(@rdivide,x,sqrt(sum(x.^2,1))); 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Tools/unitnorm.m: -------------------------------------------------------------------------------- 1 | function y = unitnorm(y) 2 | m = size(y,2); 3 | for i = 1:m 4 | y(:,i) = y(:,i)./norm( y(:,i)); 5 | end -------------------------------------------------------------------------------- /choice_of_a.m: -------------------------------------------------------------------------------- 1 | %% test different a for DCATL1 2 | 3 | M = 64; 4 | N = 256; 5 | testnum = 100; 6 | k_seq = 8:2:32; 7 | thresh = 1e-3; 8 | 9 | pm.gam = 1e-6; 10 | pm.C = 1e-9; 11 | pm.ep = 1e-6; 12 | pm.maxit = 5000; 13 | pm.maxoit = 20; 14 | pm.otol = 1e-8; 15 | pm.tol = 1e-5; 16 | pm.del = pm.gam*10; 17 | 18 | a = [0.1 0.3 1 2 10]; 19 | z = zeros(N,length(a)); 20 | succ = zeros(length(a),length(k_seq)); 21 | 22 | for j = 1:length(k_seq) 23 | j 24 | k = k_seq(j); 25 | for i = 1:testnum 26 | 27 | A = randn(M,N); 28 | x = zeros(N,1); 29 | x(randperm(N,k)) = randn(k,1); 30 | y = A*x; 31 | 32 | for l = 1:length(a) 33 | pm.a = a(l); 34 | z(:,l) = DCA_USC(A,y,pm,zeros(N,1)); 35 | err = norm(z(:,l)-x)/norm(x); 36 | if err < thresh 37 | succ(l,j) = succ(l,j) + 1; 38 | fprintf('relative error : %4.3e with a = %4.3e \n',err,pm.a); 39 | end 40 | end 41 | 42 | 43 | 44 | 45 | end 46 | end 47 | 48 | succ = succ./testnum; 49 | 50 | % graph 51 | figure 52 | x = 1:length(k_seq); 53 | 54 | plot(x,succ(1,:),'-or', x,succ(2,:),'-*b', x,succ(3,:),'-pg',... 55 | x,succ(4,:),'-dm', x,succ(5,:),'-.k','linewidth',3); 56 | axis([0 , length(k_seq)+1, 0, 1]); 57 | 58 | hleg = legend('a=0.1','a=0.3','a=1','a=2','a=10'); 59 | 60 | set(hleg,'Location','SouthWest') 61 | set(hleg,'Interpreter','none') 62 | set(gca,'XTick',x); 63 | k_label = { '8'; '10'; '12'; '14'; '16'; '18'; 64 | '20'; '22'; '24'; '26'; '28'; '30'; '32'}; 65 | 66 | set(gca,'XTickLabel',k_label); 67 | 68 | xlabel('sparsity k'); 69 | ylabel('success rate'); 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /choice_of_a.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsivine/DCATL1/44353510039bf571a944f73bcea69d94e0789cd1/choice_of_a.mat -------------------------------------------------------------------------------- /combi1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsivine/DCATL1/44353510039bf571a944f73bcea69d94e0789cd1/combi1.mat -------------------------------------------------------------------------------- /compare_test.m: -------------------------------------------------------------------------------- 1 | %% numerical test 1: Gaussian matrix 2 | % M = 64, N = 1024, r = {0:0.2:1} 3 | % k = 5:2:25 4 | M = 64; 5 | N = 1024; 6 | k = 5:2:25; 7 | for p = [0, 0.2, 0.4, 0.6 , 0.8] 8 | test_DCA(p,2,M,N,k); 9 | end 10 | 11 | %% numerical test 2: Over-sampled matrix 12 | M = 100; 13 | N = 1500; 14 | k = 25:2:35; 15 | % F = 2:2:20 16 | 17 | % for p = [2,4,6,10,12,16,20] 18 | % for p = [6,10,12,16,20] 19 | for p = [20] 20 | test_DCA(p,1,M,N,k); 21 | end 22 | 23 | 24 | % succnum = zeros(5,6); 25 | % for i = 1:5 26 | % succnum(i,:) = DCATL1_RL_sparsity(i); 27 | % end 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /muco.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zsivine/DCATL1/44353510039bf571a944f73bcea69d94e0789cd1/muco.mat -------------------------------------------------------------------------------- /shrink.m: -------------------------------------------------------------------------------- 1 | function z = shrink(x,r) 2 | z = max(0,x - r) - max(0,-x - r); 3 | end -------------------------------------------------------------------------------- /test_3Nmatrix.m: -------------------------------------------------------------------------------- 1 | function test_3Nmatrix(N) 2 | 3 | % test 3*N matrix, column vectors are generated uniformly in unit sphere 4 | % matrix A uniformly over the sphere in R^3 5 | % write the vectors in the angle variables, then sample the angles by uniform distribution 6 | test_num = 50; 7 | thresh = 1e-3; 8 | succ = zeros(3,1); 9 | 10 | % coefficient for l1-l2 11 | pm.gam = 1e-6; 12 | pm.C = 1e-9; 13 | pm.maxoit = 20; 14 | pm.tol = 1e-5; 15 | pm.del = pm.gam*10; 16 | pm.a = 1; 17 | % coefficient for IRucLq_v 18 | q = 0.5; 19 | lam2 = 1e-6; 20 | 21 | 22 | for i = 1:test_num 23 | 24 | % intialize 25 | theta = pi*(rand(1,N) -1/2); 26 | fa = 2*pi*rand(1,N); 27 | A = [cos(theta).*cos(fa);cos(theta).*sin(fa);sin(theta)]; 28 | fprintf('The mutual coherence of matrix A is %d \n', mucohere_matrix(A)); 29 | 30 | % separate two nonzeros elements with certain distance ex. N/3 31 | d = round(N/3); 32 | supp = randsample_separated(N,2,d); 33 | x = zeros(N,1); 34 | x(supp) = sign(randn(2,1)); 35 | y = A*x; 36 | 37 | % solve by different methods 38 | tic; 39 | z1 = DCA_USC(A,y,pm,zeros(N,1)); 40 | time1 = toc; 41 | tic; 42 | [z2,~] = IRucLq_v(A,y,lam2,q); 43 | time2 = toc; 44 | tic; 45 | z3 = DCAunl1_l2(A,y,pm,zeros(N,1)); 46 | time3 = toc; 47 | 48 | % tic; 49 | % pm.p = 4; 50 | % z4 = l1_lP(A,y,pm,zeros(N,1)); 51 | % time4 = toc; 52 | % tic; 53 | % pm.p = 6; 54 | % z5 = l1_lP(A,y,pm,zeros(N,1)); 55 | % time5 = toc; 56 | % tic; 57 | % pm.p = 8; 58 | % z6 = l1_lP(A,y,pm,zeros(N,1)); 59 | % time6 = toc; 60 | 61 | % display error 62 | err1 = norm(z1-x)/norm(x) 63 | if err1 < thresh 64 | succ(1) = succ(1) + 1; 65 | fprintf('relative error for DCA_USC: %4.3e, iteration time: %4.3e \n',err1,time1); 66 | end 67 | 68 | err2 = norm(z2-x)/norm(x); 69 | if err2 < thresh 70 | succ(2) = succ(2) + 1; 71 | fprintf('relative error for IRucLq_v: %4.3e, iteration time: %4.3e \n',err2,time2); 72 | end 73 | 74 | err3 = norm(z3-x)/norm(x); 75 | if err3 < thresh 76 | succ(3) = succ(3) + 1; 77 | fprintf('relative error for l1 - l2: %4.3e, iteration time: %4.3e \n',err3,time3); 78 | end 79 | 80 | % err4 = norm(z4-x)/norm(x); 81 | % if err4 < thresh 82 | % succ(4) = succ(4) + 1; 83 | % fprintf('relative error for l1 - l4: %4.3e, iteration time: %4.3e \n',err4,time4); 84 | % end 85 | % err5 = norm(z5-x)/norm(x); 86 | % if err5 < thresh 87 | % succ(5) = succ(5) + 1; 88 | % fprintf('relative error for l1 - l6: %4.3e, iteration time: %4.3e \n',err5,time5); 89 | % end 90 | % err6 = norm(z6-x)/norm(x); 91 | % if err6 < thresh 92 | % succ(6) = succ(6) + 1; 93 | % fprintf('relative error for l1 - l8: %4.3e, iteration time: %4.3e \n',err6,time6); 94 | % end 95 | 96 | subplot(2,1,1); 97 | plot(x,'o'); 98 | subplot(2,1,2); 99 | plot(z1,'*'); 100 | pause; 101 | 102 | end 103 | succ = succ./test_num; 104 | succ 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /test_DCA.m: -------------------------------------------------------------------------------- 1 | %-------------------------------------------------------------------------- 2 | % Difference of Convex Functions Methods for 1-D Compressed Sensing Problem. 3 | % 4 | % Solves 5 | % min P_a(x) 6 | % s.t. Ax = b 7 | % 8 | % Reference: "Minimization of Transformed L_1 Penalty: Theory, 9 | % Difference of Convex Function Algorithm, 10 | % and Robust Application in Compressed Sensing." 11 | % Shuai Zhang, Jack Xin 12 | % Mathematical Programming 13 | % Available at: 14 | % http://arxiv.org/abs/1411.5735 15 | % ftp://ftp.math.ucla.edu/pub/camreport/cam14-86.pdf 16 | % 17 | % Author: Shuai Zhang 18 | % Date: Feb 07. 2015 19 | %-------------------------------------------------------------------------- 20 | 21 | function test_DCA(fr,kind,M,N,k_seq) 22 | % kind: 1. Cosine matrix 23 | % 2. Gaussian matrix 24 | 25 | thresh = 1e-3; % standard for success 26 | testnum = 10; 27 | 28 | if kind == 1, 29 | F = fr; 30 | elseif kind == 2 31 | r = fr; 32 | end 33 | 34 | % k_seq = 5:2:36; 35 | len = length(k_seq); 36 | 37 | % % % % 38 | % how many methods you want to use? 39 | succ = zeros(1,len); 40 | % % % % 41 | 42 | % coefficient for l1-l2 43 | pm.gam = 1e-8; 44 | pm.C = 0; 45 | pm.ep = 1e-6; 46 | pm.maxit = 5000; 47 | pm.maxoit = 20; 48 | pm.otol = 1e-8; 49 | pm.tol = 1e-5; 50 | pm.del = pm.gam*10; 51 | 52 | pm.a = 1; 53 | 54 | 55 | % coefficient for IRucLq_v 56 | q = 0.5; 57 | lam2 = 1e-8; 58 | % opts2.s0 = round(M/2); 59 | % opts2.gamma = 0.5; 60 | 61 | % coefficient for yall1 62 | opyall.tol = 1e-5; 63 | opyall.rho = 1e-5; 64 | opyall.nonorth = 1; 65 | 66 | % coefficient for CEL0 67 | pm_cel0.lamb = 1e-5; 68 | 69 | 70 | for ii = 1:len 71 | [kind, fr, ii] 72 | k = k_seq(ii); 73 | 74 | for j = 1:testnum 75 | 76 | %% generate matrix A and right hand y 77 | if kind == 1 78 | % cosine matrix 79 | A = coherentdic(M,N,F); 80 | supp = randsample_separated(N,k,2*F); 81 | x = zeros(N,1); 82 | xx = randn(k,1); 83 | x(supp) = xx; 84 | y = A*x; 85 | 86 | % normalizing ... 87 | d = 1./sqrt(sum(A.^2,2)); 88 | A = sparse(1:M,1:M,d)*A; 89 | y = d.*y; 90 | 91 | elseif kind == 2 92 | % Gaussian matrix 93 | sigma = r*ones(N); 94 | sigma = sigma + (1-r)*eye(N); 95 | 96 | mu = zeros(1,N); 97 | A = mvnrnd(mu,sigma,M); 98 | A = unitnorm(A); 99 | 100 | xz = randn(k,1); 101 | xzs = [xz; zeros(N - size(xz,1),1) ]; 102 | ind = randperm(N); 103 | x = xzs(ind); 104 | y = A*x; 105 | 106 | % normalizing ... 107 | d = 1./sqrt(sum(A.^2,2)); 108 | A = sparse(1:M,1:M,d)*A; 109 | y = d.*y; 110 | 111 | end 112 | 113 | 114 | 115 | %% computing ... 116 | tic; 117 | z1 = DCA_TL1(A,y,pm,zeros(N,1)); 118 | time1 = toc; 119 | % tic; 120 | % [z2,~] = IRucLq_v(A,y,lam2,q); 121 | % time2 = toc; 122 | % tic; 123 | % z3 = DCAunl1_l2(A,y,pm,zeros(N,1)); 124 | % time3 = toc; 125 | % % tic; 126 | % % z4 = yall1(A,y,opyall); 127 | % % time4 = toc; 128 | % tic; 129 | % [z5,~] = macro_cel0(A,y,zeros(N,1),pm_cel0); 130 | % time5 = toc; 131 | 132 | 133 | 134 | err1 = norm(z1-x)/norm(x); 135 | if err1 < thresh 136 | succ(1,ii) = succ(1,ii) + 1; 137 | fprintf('relative error for DCATL1: %4.3e, iteration time: %4.3e \n',err1,time1); 138 | end 139 | 140 | % err2 = norm(z2-x)/norm(x); 141 | % if err2 < thresh 142 | % succ(2,ii) = succ(2,ii) + 1; 143 | % fprintf('relative error for IRucLq_v: %4.3e, iteration time: %4.3e \n',err2,time2); 144 | % end 145 | % 146 | % err3 = norm(z3-x)/norm(x); 147 | % if err3 < thresh 148 | % succ(3,ii) = succ(3,ii) + 1; 149 | % fprintf('relative error for l1 - l2: %4.3e, iteration time: %4.3e \n',err3,time3); 150 | % end 151 | 152 | % err4 = norm(z4-x)/norm(x); 153 | % if err4 < thresh 154 | % succ(4,ii) = succ(4,ii) + 1; 155 | % fprintf('relative error for yall1: %4.3e, iteration time: %4.3e \n',err4,time4); 156 | % end 157 | 158 | % err5 = norm(z5-x)/norm(x); 159 | % if err5 < thresh 160 | % succ(4,ii) = succ(4,ii) + 1; 161 | % fprintf('relative error for CEL0: %4.3e, iteration time: %4.3e \n',err5,time5); 162 | % end 163 | 164 | % tic; 165 | % pm.p = 4; 166 | % z4 = l1_lP(A,y,pm,zeros(N,1)); 167 | % time4 = toc; 168 | % tic; 169 | % pm.p = 6; 170 | % z5 = l1_lP(A,y,pm,zeros(N,1)); 171 | % time5 = toc; 172 | % tic; 173 | % pm.p = 8; 174 | % z6 = l1_lP(A,y,pm,zeros(N,1)); 175 | % time6 = toc; 176 | % err4 = norm(z4-x)/norm(x); 177 | % if err4 < thresh 178 | % succ(4,i) = succ(4,i) + 1; 179 | % fprintf('relative error for l1 - l4: %4.3e, iteration time: %4.3e \n',err4,time4); 180 | % end 181 | % err5 = norm(z5-x)/norm(x); 182 | % if err5 < thresh 183 | % succ(5,i) = succ(5,i) + 1; 184 | % fprintf('relative error for l1 - l6: %4.3e, iteration time: %4.3e \n',err5,time5); 185 | % end 186 | % err6 = norm(z6-x)/norm(x); 187 | % if err6 < thresh 188 | % succ(6,i) = succ(6,i) + 1; 189 | % fprintf('relative error for l1 - l8: %4.3e, iteration time: %4.3e \n',err6,time6); 190 | % end 191 | 192 | fprintf('\n'); 193 | end 194 | end 195 | 196 | succ = succ./testnum; 197 | succ 198 | 199 | %% graph 200 | % figure 201 | % x = 1:len; 202 | % 203 | % plot(x,succ(1,:),'-ro', x,succ(2,:),'-*b', x,succ(3,:),'-g',... 204 | % x,succ(4,:),'-.k', 'linewidth',3); 205 | % axis([0 , len+1, 0, 1]); 206 | % 207 | % hleg = legend('DCATL1','IRucLq_v','DCA l1-l2','CEL0'); 208 | % 209 | % set(hleg,'Location','SouthWest') 210 | % set(hleg,'Interpreter','none') 211 | % set(gca,'XTick',x); 212 | % 213 | % if kind == 1 214 | % k_label = { '5'; '7'; '9'; '11'; '13'; '15'; 215 | % '17'; '19'; '21'; '23'; '25'; '27'; 216 | % '29'; '31'; '33'; '35'}; 217 | % title('Over-sampled matrix with M = 100, N = 1500, F = '); 218 | % elseif kind == 2 219 | % k_label = { '5'; '7'; '9'; '11'; '13'; '15'; 220 | % '17'; '19'; '21'; '23'; '25'}; 221 | % title('Gaussian Matrix with M = 64, N = 1024, r = '); 222 | % end 223 | % 224 | % set(gca,'XTickLabel',k_label); 225 | % 226 | % 227 | % xlabel('sparsity k'); 228 | 229 | 230 | 231 | 232 | 233 | 234 | -------------------------------------------------------------------------------- /test_TIME.m: -------------------------------------------------------------------------------- 1 | clc, close all, clear; 2 | M = 64; N = 1024; 3 | F = 2; 4 | K = 10; 5 | 6 | % % linear system 7 | % A = zeros(M,N); 8 | % r = rand(M,1); 9 | % l = 1:N; 10 | % for k = 1:M 11 | % A(k,:) = sqrt(1/M)*cos(2*pi*r(k)*(l-1)/F); 12 | % end 13 | % 14 | % supp = randsample_separated(N,K,2*F); 15 | % x = zeros(N,1); 16 | % xs = randn(K,1); 17 | % x(supp) = xs; 18 | % b = A*x; 19 | 20 | r = 0.0; 21 | sigma = r*ones(N); 22 | sigma = sigma + (1-r)*eye(N); 23 | mu = zeros(1,N); 24 | A = mvnrnd(mu,sigma,M); 25 | A = unitnorm(A); 26 | xz = randn(K,1); 27 | xzs = [xz; zeros(N - size(xz,1),1) ]; 28 | ind = randperm(N); 29 | x = xzs(ind); 30 | b = A*x; 31 | 32 | % % normalizing ... 33 | % d = 1./sqrt(sum(A.^2,2)); 34 | % A = sparse(1:M,1:M,d)*A; 35 | % y = d.*y; 36 | 37 | 38 | % load data.mat 39 | % N = size(A,2); 40 | % parameters 41 | pm.gam = 1e-8; 42 | pm.C = 0; 43 | pm.ep = 1e-6; 44 | pm.maxit = 5000; 45 | pm.maxoit = 20; 46 | pm.otol = 1e-8; 47 | pm.tol = 1e-5; 48 | pm.del = pm.gam*10; 49 | pm.a = 1; 50 | 51 | 52 | %opts1.x0 = randn(N,1); 53 | % opts1.so = round(K); 54 | % opts1.maxit = 5000; 55 | % opts1.tol = 1e-06; 56 | % opts1.gamma = 0.5; opts1.eps0 = 1; 57 | % lam1 = 1e-6; 58 | 59 | 60 | % tic; 61 | % x1 = Cons_DCATL1(A,b,[],zeros(N,1)); 62 | % time1 = toc; 63 | % tic; 64 | % x2 = Cons_DCATL1_Linprog(A,b,[],zeros(N,1)); 65 | % time2 = toc; 66 | % tic; 67 | % x3 = Cons_DCATL1_Linprog_v2(A,b,[],zeros(N,1)); 68 | % time3 = toc; 69 | 70 | 71 | tic; 72 | x1 = DCA_TL1(A,b,pm,zeros(N,1)); 73 | time1 = toc; 74 | tic; 75 | 76 | 77 | time1 78 | 79 | relerr1 = norm(x1-x)/norm(x) 80 | subplot(2,1,1); 81 | plot(x); 82 | subplot(2,1,2); 83 | plot(x1); 84 | 85 | 86 | 87 | 88 | 89 | --------------------------------------------------------------------------------