function proxAk = prox_A(Ak,options)
%calculates the proximal operator of P_i for any matrix Ak
%
%Input
% Ak M*N*K matrix
% option Object containing the choice of \lambda and P_i:
%
% option.lambda \lambda constant of problem (2)
% option.tR \p=ell_1 norm for t
tR
% option.rescale \rho(t): expected time enveloppe of filters
% option.lipschitz Lipschitz constant of \nabla A\mapsto \frac{1}{2}\|\X-\A\star \s\|_2^2
%Output
%
% proxAk M*N*K matrix equals to proxAk=prox_{\frac{\lambda}{options.lipschitz} P_i}(Ak)
%
L=options.lambda;
%case prox=Identity
if L==0 || nnz(Ak)==0;
proxAk=Ak;
return;
end
tR=options.tR;
seuil=(1/options.lipschitz)*L;
rescale=options.rescale;
[M N K]=size(Ak);
%prox_{\lambda L2 norm}(Ak)
r2=seuil./(rescale(:,:,tR+1:end).^2)+1;
prox_l2=Ak(:,:,tR+1:end)./r2;
%prox_{\lambda L1 norm}
Ak_l1=Ak(:,:,1:tR).*rescale(:,:,1:tR);
%[Mtr,Ntr,N] = size(dccS);
arg = zeros(M,N,tR); %in the case of real numbers, argAk computes the sign of Ak
arg(Ak_l1~=0) = Ak_l1(Ak_l1~=0)./abs(Ak_l1(Ak_l1~=0)) ;
prox_l1 = arg.*seuildoux(abs(Ak_l1),seuil);
prox_l1=prox_l1./rescale(:,:,1:tR);
%concatenation of both operators
proxAk=cat(3,prox_l1,prox_l2);
end
% Written by Matthieu Kowalski, 2010
% Updated by Alexis Benichoux, 2011