time | Calls | line |
---|
| | 1 | function output = run_admm(output,C_tilde,Bhat_blk,U,V,opts)
|
| | 2 |
|
| | 3 | % this function runs the alternating direction method of multipliers(ADMM)
|
| | 4 | %
|
| | 5 | % timer
|
| | 6 |
|
0.026 | 1 | 7 | fprintf('admm starts here: \n')
|
0.008 | 1 | 8 | admm_t = tic;
|
| | 9 |
|
< 0.001 | 1 | 10 | m = length(C_tilde)-1;
|
| | 11 |
|
0.003 | 1 | 12 | maxit = opts.maxit;
|
0.002 | 1 | 13 | beta = opts.beta;
|
< 0.001 | 1 | 14 | gamma = opts.gamma;
|
< 0.001 | 1 | 15 | scalar = opts.scalar;
|
< 0.001 | 1 | 16 | tol = opts.tol;
|
| | 17 |
|
< 0.001 | 1 | 18 | blk_sizes = output.blk_sizes;
|
< 0.001 | 1 | 19 | blk_nz = output.blk_nz;
|
| | 20 |
|
| | 21 |
|
< 0.001 | 1 | 22 | B_mat_mean = output.B_mat_mean;
|
0.009 | 1 | 23 | B_matrix = output.B_mat;
|
| | 24 |
|
| | 25 |
|
| | 26 |
|
< 0.001 | 1 | 27 | orbit_size = size(B_matrix,2);
|
< 0.001 | 1 | 28 | nr_blocks = length(blk_sizes);
|
0.006 | 1 | 29 | bt = cumsum(blk_sizes); % the end index of each blocks
|
0.006 | 1 | 30 | bs = [1; bt(1:end-1)+1]; % the begin index of each blocks
|
| | 31 |
|
| | 32 | % Initialization of the alternating direction method of multipliers(ADMM)
|
| | 33 |
|
| | 34 | % preallocate variables
|
< 0.001 | 1 | 35 | fvals = zeros(maxit,1);
|
< 0.001 | 1 | 36 | p_res = zeros(maxit,1);
|
0.001 | 1 | 37 | d_res = zeros(maxit,1);
|
| | 38 |
|
0.002 | 1 | 39 | Z = cell(nr_blocks,1);
|
< 0.001 | 1 | 40 | R = cell(nr_blocks,1);
|
< 0.001 | 1 | 41 | VRV = cell(nr_blocks,1);
|
< 0.001 | 1 | 42 | U_blk = cell(nr_blocks,1); % columns of U associated to the k-th block of Y
|
< 0.001 | 1 | 43 | C_blk = cell(nr_blocks,1); % k-th block of U'A0U
|
< 0.001 | 1 | 44 | Bhat_x = cell(nr_blocks,1); % Bhat_x contains k-th block of sum \hat{B}^{*}_{i}x_{i}
|
< 0.001 | 1 | 45 | block_z = cell(nr_blocks,1); % the zero pattern of k-th block
|
| | 46 |
|
| | 47 | % initial value of x
|
| | 48 | % x = rand(orbit_size,1);
|
< 0.001 | 1 | 49 | x = zeros(orbit_size,1); % initialize with zeros has superior convergence
|
| | 50 | % x(1) = 1;
|
0.002 | 1 | 51 | for i = 1:nr_blocks
|
| | 52 |
|
| | 53 | % initial value of Z
|
0.012 | 198 | 54 | Z{i} = zeros(blk_sizes(i));
|
22.844 | 198 | 55 | Z{i}(:) = Bhat_blk{i}*x;
|
| | 56 |
|
| | 57 | % initial value of R
|
0.024 | 198 | 58 | R{i} = zeros(size(V{i},2));
|
| | 59 |
|
| | 60 | % initialize variables
|
0.021 | 198 | 61 | idx = bs(i):bt(i); % idx for the i-th block of Y
|
0.142 | 198 | 62 | U_blk{i} = U(:,idx);
|
0.047 | 198 | 63 | C_blk{i} = C_tilde(idx,idx);
|
0.029 | 198 | 64 | Bhat_x{i} = zeros(blk_sizes(i));
|
0.020 | 198 | 65 | block_z{i} = ~blk_nz(idx,idx);
|
0.004 | 198 | 66 | end
|
| | 67 |
|
| | 68 |
|
| | 69 | %%
|
0.007 | 1 | 70 | VRV_CZ = cell(nr_blocks,1);
|
| | 71 |
|
| | 72 | %% execute ADMM
|
0.005 | 1 | 73 | for k = 1:maxit
|
| | 74 |
|
| | 75 | % ==========solve the R-subproblem=========
|
0.592 | 14189 | 76 | Rold=R;
|
0.002 | 14189 | 77 | Rdiff = 0;
|
0.006 | 14189 | 78 | for i = 1:nr_blocks
|
| | 79 |
|
45.959 | 2809422 | 80 | VBZV = V{i}'*(Bhat_x{i}+(1/beta)*Z{i})*V{i};
|
7.372 | 2809422 | 81 | VBZV = (VBZV+VBZV')/2;
|
| | 82 |
|
| | 83 | % R{i} = proj_psd(VBZV);
|
0.601 | 2809422 | 84 | if size(V{i},1) > 1
|
276.719 | 85134 | 85 | R{i} = proj_psd(VBZV);
|
0.138 | 2724288 | 86 | else
|
0.266 | 2724288 | 87 | if VBZV < 0
|
| | 88 | R{i} = 0;
|
0.131 | 2724288 | 89 | else
|
1.319 | 2724288 | 90 | R{i} = VBZV;
|
0.163 | 2724288 | 91 | end
|
0.143 | 2809422 | 92 | end
|
| | 93 | % if norm(R2{i}-R{i}) > 1e-3
|
| | 94 | % keyboard
|
| | 95 | % end
|
8.453 | 2809422 | 96 | Rdiff = Rdiff + norm(Rold{i}-R{i},'fro');
|
0.209 | 2809422 | 97 | end
|
| | 98 |
|
| | 99 | % ==========solve the x-subproblem=========
|
0.063 | 14189 | 100 | xold=x;
|
| | 101 |
|
| | 102 | %%%%% (*) is slower than (**)???????
|
| | 103 | % (*)
|
| | 104 | % M = zeros(m+1);
|
| | 105 | % for i = 1:nr_blocks
|
| | 106 | % VRV{i} = V{i}*R{i}*V{i}';
|
| | 107 | % M = M + U_blk{i}*(VRV{i} -(C_blk{i}+Z{i})/beta)*U_blk{i}';
|
| | 108 | % end
|
| | 109 | % M = (M+M')/2;
|
| | 110 |
|
| | 111 |
|
| | 112 | % (*)
|
0.005 | 14189 | 113 | for i = 1:nr_blocks
|
48.638 | 2809422 | 114 | VRV{i} = V{i}*R{i}*V{i}';
|
9.910 | 2809422 | 115 | VRV_CZ{i} = VRV{i}-(C_blk{i}+Z{i})/beta;
|
0.197 | 2809422 | 116 | end
|
892.634 | 14189 | 117 | M1 = U*blkdiag(VRV_CZ{:})*U';
|
130.925 | 14189 | 118 | M = (M1+M1')/2;
|
| | 119 |
|
| | 120 |
|
| | 121 |
|
47.872 | 14189 | 122 | x = B_mat_mean*M(:);
|
0.451 | 14189 | 123 | x = max(min(x,1),0);
|
0.003 | 14189 | 124 | x(1) = 1;
|
0.446 | 14189 | 125 | xdiff=norm(xold-x);
|
| | 126 |
|
| | 127 | %==========dual variable Z-update=========
|
1.003 | 14189 | 128 | Z_old = Z;
|
0.007 | 14189 | 129 | for i = 1:nr_blocks
|
3699.313 | 2809422 | 130 | Bhat_x{i}(:) = Bhat_blk{i}*x; % precompute
|
9.296 | 2809422 | 131 | Z{i} = Z{i} + gamma*beta*(Bhat_x{i}-VRV{i}); % update the dual variable
|
9.523 | 2809422 | 132 | Z{i} = (Z{i}+Z{i}')/2;
|
11.648 | 2809422 | 133 | Z{i}(block_z{i}) = 0; % set entries to zero based on zero-pattern
|
0.213 | 2809422 | 134 | end
|
| | 135 |
|
| | 136 | %==========update obj&res values==========
|
| | 137 | %%%%% no need for f_vals(k)????????????????????
|
0.006 | 14189 | 138 | for i = 1:nr_blocks
|
34.102 | 2809422 | 139 | fvals(k) = fvals(k) + trace(C_blk{i}*Bhat_x{i})/scalar;
|
8.619 | 2809422 | 140 | p_res(k) = p_res(k) + norm(Bhat_x{i}-VRV{i},'fro');
|
8.233 | 2809422 | 141 | d_res(k) = d_res(k) + norm(Z_old{i}-Z{i},'fro');
|
0.171 | 2809422 | 142 | end
|
| | 143 |
|
| | 144 | %==========print the information==========
|
0.268 | 14189 | 145 | print_admm(k, fvals(k), p_res(k),d_res(k),Rdiff,xdiff, 0);
|
| | 146 |
|
| | 147 | % ==========stopping criterions==========
|
| | 148 | % STOP when the step-size is less than tol
|
0.063 | 14189 | 149 | if (xdiff < tol)&&(Rdiff < tol)
|
0.033 | 1 | 150 | output.exitflag = 'converged';
|
0.007 | 1 | 151 | print_admm(k, fvals(k), p_res(k),d_res(k),Rdiff,xdiff, 1);
|
0.015 | 1 | 152 | break
|
| | 153 | end
|
0.004 | 14188 | 154 | end
|
| | 155 |
|
| | 156 | % timer and the optimal solution/value
|
0.013 | 1 | 157 | admm_t = toc(admm_t);
|
0.093 | 1 | 158 | Y = reshape(B_matrix*x,m+1,m+1);
|
< 0.001 | 1 | 159 | fval = fvals(k);
|
| | 160 |
|
| | 161 | % save the output
|
0.091 | 1 | 162 | output = save_output(output,x,R,Z,Y,admm_t,k,fvals,p_res,d_res);
|
| | 163 |
|
| | 164 | % ==========print the outputs==========
|
0.055 | 1 | 165 | print_output(output)
|
0.015 | 1 | 166 | end
|
Other subfunctions in this file are not included in this listing.