function out = sparse_low_rank_decomp_ALM_SADAL_smoothed(D, opts)

[m,n] = size(D); 
mu = opts.mu; sigma = opts.sigma; rho = opts.rho;
Y = zeros(m,n); gradgY = zeros(m,n);
X = D - Y; Dnorm = norm(D,'fro'); num_unchange_mu = 0; 
X = zeros(m,n); 
Lambda = zeros(m,n); sv = opts.sv;

Lambda = D;
%norm_two = lansvd(Lambda, 1, 'L');
norm_inf = norm( Lambda(:), inf) / rho;
norm_two = norm_inf; 
dual_norm = max(norm_two, norm_inf);
Lambda = Lambda / dual_norm;

for itr = 1: opts.maxitr
%     [U,gamma,V] = svd(mu*Lambda-Y+D,'econ');
%     sv = sv + round(n*0.1);
      if itr == 2
          Lambda = -min(rho,max(-rho,Y/sigma));
      end     

%     if choosvd(n, sv) == 1
%         [U, gamma, V] = lansvd(mu*Lambda-Y+D,sv,'L');
%     else
         [U, gamma, V] = svd(mu*Lambda-Y+D, 'econ');
%     end
%     [U, gamma, V] = lansvd(mu*Lambda-Y+D,sv,'L');
%        [U, gamma, V] = svd(mu*Lambda-Y+D, 'econ');
    gamma = diag(gamma);
%     gamma_new = max(gamma-mu,0);
    gamma_new = gamma-mu*gamma./max(gamma,mu+sigma);
    svp = length(find(gamma > mu));
%     svp = length(find(gamma_new > 0));
    if svp < sv
        sv = min(svp + 1, n);
    else
%         sv = min(svp + 5, n);
        sv = min(svp + round(0.05*n), n);
    end

    Xp = X;
    X = U*diag(gamma_new)*V';
%     if mu < 1e-2
        Lambda = Lambda - (X+Y-D)/mu;
%         opts.eta_mu = 1/4;
%     end
%     gradfX = U*diag(min(gamma_new/sigma,1))*V';
    B = Lambda - (X-D)/mu;
    Yp = Y;
%     Y = shrink(mu*Lambda+D-X,mu*rho);

    Y = mu*B - mu*min(rho, max(-rho,mu*B/(sigma+mu)));
%     mumgradgY = min(mu*rho,max(-mu*rho,Y*muoversigma));
%     gradgY = min(rho,max(-rho,Y/sigma));
    Lambda = Lambda - (X+Y-D)/mu;
    
    StopCrit = norm(D-X-Y,'fro')/Dnorm; 
    relX = norm(X-opts.Xs,'fro')/norm(opts.Xs,'fro');
    relY = norm(Y-opts.Ys,'fro')/norm(opts.Ys,'fro');
    diffX = norm(Xp-X,'fro')/max(1,norm(X,'fro'));
    diffY = norm(Yp-Y,'fro')/max(1,norm(Y,'fro'));
    fprintf('iter: %d, mu: %3.2e, rank(X):%d, relX: %3.2e, relY: %3.2e,crit:%3.2e\n', ...
        itr, mu, length(find(gamma_new>1e-3)), relX, relY, norm(D-X-Y,'fro')/norm(D,'fro'));
    num_unchange_mu = num_unchange_mu + 1; 
%     if norm(X-opts.Xs,'fro')/Dnorm < tolProj || num_unchange_mu > 3
        mu = max(opts.muf, mu*opts.eta_mu);
        sigma = max(opts.sigmaf, sigma*opts.eta_sigma);
        num_unchange_mu = 0;
%     end
    % check stop
    
    if StopCrit < opts.epsilon
        out.X = X; out.Y = Y; out.iter = itr; out.relX = relX; out.relY = relY; out.StopCrit = StopCrit;
        return;
    end
end
out.X = X; out.Y = Y; out.iter = itr; out.relX = relX; out.relY = relY; out.StopCrit = StopCrit;
