function[path, relative_error] = PGD_Lowrank(X, Y, A0, kmax, Astar)

% PGD_Lowrank    Solve low-rank transition estimation by PGD
% [path, relative_error] = PGD_Lowrank(X, Y, A0, kmax, Astar)
% X - Data matrix
% Y - Measurement matrix
% A0 - Initial point
% kmax - Maximum iteration
% Astar - Real transition matrix
% path - Path of iteration points
% relative_error - Relative errors of iteration points

[n, d] = size(X);

%%%%%Initialization
path = [];
relative_error = [];

k = 0;

%%%%%Step size
S = 1 / n * X' * X;
tk = 1 / max(eig(S)) / n ;

vecAstar = reshape(Astar', d * d, 1);
D = norm(svd(Astar), 1);

while k <= kmax
    
    temp = A0 - tk * X' * (X * A0 - Y');
    
    
    [U, Sigma, V] = svd(temp);
    SigmaPGD = diag(ProjectOntoL1Ball(diag(Sigma), D));
    A = U * SigmaPGD * V';
    
    z = reshape(A, d*d, 1);
    
    A0 = A;
        
    k = k + 1;
    path = [path, z];

    relative_error = [relative_error, norm(z - vecAstar) / norm(vecAstar)];

end
end