 function [tildex,x,iter,time,xADMM,zADMM,yADMM] = ADMM_CS_LY_S(A0,v,b,mu,w,L,beta,sigmabd,maxiter,disp,xADMM,zADMM,yADMM,xstar,tol_mu,xold1,tol_tau)

% This code solves 
% min ||w.*x||_1 s.t. ||Ax - b|| <= mu
% using ADMM with proximal term
%
% Input
% A, b, mu, w - problem data
% L          - upper bound of lambda_max(A'*A)
% beta       - penalty parameter in ADMM
% tol        - Termination tolerance (relative gap)
% maxiter    - max number of iteration
% disp       - disp frequency
%
% Output
% x          - approximate optimal solution
% iter       - number of iterations
% time       - time elapsed

tstart = tic;
% Initialization
x = xADMM; % initial point
z = zADMM;
y = yADMM;

Ahandle = @(x) v.*(A0*x);
AThandle = @(x) A0'*(v.*x);

Ax = Ahandle(x);
r = Ax - y - b;
ATr = AThandle(r);
ATb = AThandle(b);
ATz = AThandle(z);
%Lbeta = L*beta
gamma = (sqrt(5) + 1)/2*0.99;

iter = 0;
while iter <= maxiter
    
    yold = y;
    xold = x;
    zold = z;
    ATrold = ATr;
    
    % x update (adding w in line 40)
    tmp = ATr - ATz/beta;
    xtmp = x - tmp/L;
    x = sign(xtmp).*max(abs(xtmp) - w/L/beta,0);
    Ax = Ahandle(x);
    tmp = norm(b - Ax);
  if tmp > mu
      tildex = (1 - mu/tmp)*xstar + mu/tmp*x;
  else
      tildex = x;
  end
    
    % y update
    ytmp = Ax - b - z/beta;
    normytmp = norm(ytmp);
    y = min(mu/normytmp, 1) * ytmp;
    
    r = Ax - y - b;
    ATr = AThandle(r);
    
    % z update
    z = z - gamma*beta*r;
    ATz = ATz - gamma*beta*ATr; 
  

    succ_xch = x - xold;
    succ_ych = y - yold;
    succ_zch = z - zold;
    succ_change = (norm(succ_xch) + norm(succ_ych) + norm(succ_zch))/(norm(x) + norm(y) + norm(z) + 1);
    
    % Display
    if mod(iter,disp) == 0
        fprintf(' Iter = %5.0f,  succ = %3.2e\n', iter,  succ_change)
    end
    
    % Test for termination
    betaATAsucc_xy = beta*(ATr - ATrold);
    tolsub = betaATAsucc_xy - L*beta*succ_xch;


    if norm(tolsub) <= min(sigmabd, tol_tau*(beta*norm(ATr + ATb - L*x) + 1)) && norm(succ_zch) <= gamma*beta*(min(sigmabd,tol_tau*(norm(z) + 1)))  && norm(w.*tildex,1) <= norm(w.*xold1,1) +tol_mu 

       break
    end

    
  iter = iter + 1; 
    
  
  
end
time = toc(tstart);

xADMM = x;
zADMM = z;
yADMM = y;
   


    