0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 function [xk_1, lambdak_1, gamma_xk, gamma_lambdak, iter, th] = DS_homotopy_function(A, y, thresh, maxiter);
0032
0033 N = size(A,2);
0034 M = size(A,1);
0035 t0 = cputime;
0036 if (nargin < 4), maxiter = 10*M; end
0037
0038
0039 z_x = zeros(N,1);
0040 z_lambda = zeros(N,1);
0041 gamma_lambda = [];
0042 gamma_x = [];
0043
0044
0045 Primal_constrk = -A'*y;
0046 [c i] = max(abs(Primal_constrk));
0047
0048 gamma_lambdak = i;
0049 gamma_xk = gamma_lambdak;
0050
0051 z_lambda(gamma_lambdak) = sign(Primal_constrk(gamma_lambdak));
0052 epsilon = c;
0053 Primal_constrk(gamma_lambdak) = sign(Primal_constrk(gamma_lambdak))*epsilon;
0054 xk_1 = zeros(N,1);
0055
0056 lambdak_1 = zeros(N,1);
0057 lambdak_1(gamma_lambdak) = inv(A(:,gamma_lambdak)'*A(:,gamma_lambdak))*z_lambda(gamma_lambdak);
0058
0059 Dual_constrk = A'*(A*lambdak_1);
0060
0061 z_x(gamma_xk) = -sign(Dual_constrk(gamma_xk));
0062 Dual_constrk(gamma_xk) = sign(Dual_constrk(gamma_xk));
0063
0064 z_xk = z_x;
0065 z_lambdak = z_lambda;
0066
0067
0068 done = 0;
0069 iter = 0;
0070 data_precision = eps;
0071
0072 old_delta = 0;
0073 out_lambda = [];
0074 out_x = [];
0075 count_delta_stop = 0;
0076
0077 AtglAgx = A(:,gamma_lambdak)'*A(:,gamma_xk);
0078 iAtglAgx = inv(A(:,gamma_lambdak)'*A(:,gamma_xk));
0079 AtgxAgl = AtglAgx';
0080 iAtgxAgl = iAtglAgx';
0081
0082 while iter < maxiter
0083 iter = iter+1;
0084
0085
0086 gamma_x = gamma_xk;
0087 gamma_lambda = gamma_lambdak;
0088 z_lambda = z_lambdak;
0089 z_x = z_xk;
0090 x_k = xk_1;
0091 lambda_k = lambdak_1;
0092
0093
0094
0095
0096
0097
0098
0099 del_x = -iAtglAgx*z_lambda(gamma_lambda);
0100 del_x_vec = zeros(N,1);
0101 del_x_vec(gamma_x) = del_x;
0102
0103 pk = Primal_constrk;
0104
0105 Agdelx = A(:,gamma_x)*del_x;
0106 dk = A'*Agdelx;
0107
0108
0109 pk_temp = Primal_constrk;
0110 gammaL_temp = find(abs(abs(Primal_constrk)-epsilon)<min(epsilon,1e-12));
0111 pk_temp(gammaL_temp) = sign(Primal_constrk(gammaL_temp))*epsilon;
0112
0113 xk_temp = x_k;
0114 gammaX_temp = find(abs(x_k)<1*eps);
0115 xk_temp(gammaX_temp) = 0;
0116
0117
0118
0119 [i_delta, out_x, delta, chk_x] = update_primal(gamma_x, gamma_lambda, z_x, xk_temp, del_x_vec, pk_temp, dk, epsilon, out_lambda);
0120
0121 if old_delta < 4*eps & delta < 4*eps
0122 count_delta_stop = count_delta_stop + 1;
0123 else
0124 count_delta_stop = 0;
0125 end
0126 if count_delta_stop >= 50
0127 disp('stuck in some corner');
0128 break;
0129 end
0130 old_delta = delta;
0131
0132 xk_1 = x_k+delta*del_x_vec;
0133 Primal_constrk = pk+delta*dk;
0134 epsilon_old = epsilon;
0135 epsilon = epsilon-delta;
0136 if epsilon < thresh;
0137 xk_1 = x_k + (epsilon_old-thresh)*del_x_vec;
0138 break;
0139 end
0140
0141 if chk_x == 1
0142
0143 out_x = out_x(1);
0144 gl_old = gamma_lambda;
0145 gx_old = gamma_x;
0146
0147 outx_index = find(gamma_x==out_x);
0148 gamma_x(outx_index) = gamma_x(end);
0149 gamma_x(end) = out_x;
0150 gamma_x = gamma_x(1:end-1);
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 [max_val outl_index] = max(abs(iAtgxAgl(:,outx_index)));
0165 new_lambda = gamma_lambda(outl_index);
0166 some_lambda = new_lambda;
0167
0168 outl_index = find(gamma_lambda==some_lambda);
0169 gamma_lambda(outl_index) = gamma_lambda(end);
0170 gamma_lambda(end) = some_lambda;
0171 gamma_lambdak = gamma_lambda;
0172 gamma_lambda = gamma_lambda(1:end-1);
0173
0174 rowi = outx_index;
0175 colj = outl_index;
0176 AtgxAgl_ij = AtgxAgl;
0177 temp_row = AtgxAgl_ij(rowi,:);
0178 AtgxAgl_ij(rowi,:) = AtgxAgl_ij(end,:);
0179 AtgxAgl_ij(end,:) = temp_row;
0180 temp_col = AtgxAgl_ij(:,colj);
0181 AtgxAgl_ij(:,colj) = AtgxAgl_ij(:,end);
0182 AtgxAgl_ij(:,end) = temp_col;
0183 iAtgxAgl_ij = iAtgxAgl;
0184 temp_row = iAtgxAgl_ij(colj,:);
0185 iAtgxAgl_ij(colj,:) = iAtgxAgl_ij(end,:);
0186 iAtgxAgl_ij(end,:) = temp_row;
0187 temp_col = iAtgxAgl_ij(:,rowi);
0188 iAtgxAgl_ij(:,rowi) = iAtgxAgl_ij(:,end);
0189 iAtgxAgl_ij(:,end) = temp_col;
0190
0191 AtgxAgl = AtgxAgl_ij(1:end-1,1:end-1);
0192 AtglAgx = AtgxAgl';
0193 iAtgxAgl = update_inverse(AtgxAgl_ij, iAtgxAgl_ij,2);
0194 iAtglAgx = iAtgxAgl';
0195 xk_1(out_x) = 0;
0196 else
0197
0198 gamma_lambdak = [gamma_lambda; i_delta];
0199 new_lambda = i_delta;
0200 lambda_k(new_lambda) = 0;
0201 end
0202
0203 out_lambda = [];
0204 z_lambdak = zeros(N,1);
0205 z_lambdak(gamma_lambdak) = sign(Primal_constrk(gamma_lambdak));
0206 sgn_new_lambda = sign(Primal_constrk(new_lambda));
0207 Primal_constrk(gamma_lambdak) = sign(Primal_constrk(gamma_lambdak))*epsilon;
0208
0209
0210
0211
0212
0213
0214 sgn_new_lambda = sign(Primal_constrk(new_lambda));
0215
0216 AtgxAnl = A(:,gamma_x)'*A(:,new_lambda);
0217
0218
0219
0220
0221 del_lambda = -iAtgxAgl*AtgxAnl;
0222 del_lambda_p = zeros(N,1);
0223 del_lambda_p(gamma_lambda) = del_lambda*sgn_new_lambda;
0224 del_lambda_p(new_lambda) = 1*sgn_new_lambda;
0225
0226 ak = Dual_constrk;
0227
0228 Agdel_lam = A(:,[gamma_lambda; new_lambda])*del_lambda_p([gamma_lambda; new_lambda]);
0229 bk = A'*Agdel_lam;
0230
0231
0232 if sign(bk(out_x)) == sign(ak(out_x)) & abs(bk(out_x)) >=eps
0233 bk = -bk;
0234 del_lambda_p = -del_lambda_p;
0235 end
0236
0237
0238 ak_temp = Dual_constrk;
0239 gammaX_temp = find(abs(abs(Dual_constrk)-1)<2*eps);
0240 ak_temp(gammaX_temp) = sign(Dual_constrk(gammaX_temp));
0241
0242 lambdak_temp = lambda_k;
0243 gammaL_temp = find(abs(lambda_k)<1*eps);
0244 lambdak_temp(gammaL_temp) = 0;
0245
0246
0247
0248 [i_theta, out_lambda, theta, chk_lambda] = update_dual(gamma_x, gamma_lambda, z_lambda, lambdak_temp, del_lambda_p, ak_temp, bk, new_lambda, out_x);
0249
0250 out_x = [];
0251
0252 lambdak_1 = lambda_k + theta*del_lambda_p;
0253 Dual_constrk = ak+theta*bk;
0254
0255 if chk_lambda == 1
0256
0257 outl_index = find(gamma_lambda==out_lambda);
0258 i_theta = gamma_x(end);
0259
0260 if ~isempty(outl_index)
0261
0262
0263 iA = iAtgxAgl;
0264 B = AtgxAnl-A(:,gamma_x)'*A(:,out_lambda);
0265 C = zeros(1,length(gamma_lambda));
0266 C(outl_index) = 1;
0267 AtgxAgl(:,outl_index) = AtgxAnl;
0268 AtglAgx = AtgxAgl';
0269
0270 iAB = iA*B;
0271 CiA = iA(outl_index,:);
0272 iAtgxAgl = iA-iAB*((CiA)/(1+iAB(outl_index)));
0273 iAtglAgx = iAtgxAgl';
0274
0275 gamma_lambda(outl_index) = new_lambda;
0276 end
0277
0278 z_xk = zeros(N,1);
0279 z_xk(gamma_x) = -sign(Dual_constrk(gamma_x));
0280 lambdak_1(out_lambda) = 0;
0281 else
0282
0283
0284
0285
0286 AtglAgx_mod = [AtglAgx A(:,gamma_lambda)'*A(:,i_theta); AtgxAnl' A(:,new_lambda)'*A(:,i_theta)];
0287
0288
0289
0290
0291
0292
0293 A11 = AtglAgx;
0294 A12 = AtglAgx_mod(1:end-1,end);
0295 A21 = AtglAgx_mod(end,1:end-1);
0296 A22 = AtglAgx_mod(end,end);
0297 S = A22 - A21*(iAtglAgx*A12);
0298 if abs(S) < 2*eps
0299 disp('matrix has become singular');
0300
0301
0302 end
0303 AtglAgx = AtglAgx_mod;
0304 AtgxAgl = AtglAgx';
0305 iAtglAgx = update_inverse(AtglAgx, iAtglAgx,1);
0306 iAtgxAgl = iAtglAgx';
0307
0308 out_lambda = [];
0309 gamma_lambda = [gamma_lambda; new_lambda];
0310
0311 gamma_x = [gamma_x; i_theta];
0312 z_xk = zeros(N,1);
0313 z_xk(gamma_x) = -sign(Dual_constrk(gamma_x));
0314 xk_1(i_theta) = 0;
0315 end
0316 Dual_constrk(gamma_x) = sign(Dual_constrk(gamma_x));
0317 gamma_lambdak = gamma_lambda;
0318 gamma_xk = gamma_x;
0319 end
0320 th = cputime-t0;