clc;
clear all;

% Curves of squared estimation error vs. number of measurements under different ambient dimensions
% Curves of squared estimation error vs. number of measurements rescaled by Gaussian width under different ambient dimensions

addpath(genpath('..\Software_Linear_Convergence_VAR'));

nLength = 10;
%%%%%Different numbers of measurements
n = ceil([linspace(1000, 4000, nLength); linspace(1000, 5000, nLength); linspace(1000, 6000, nLength)]);

%%%%%Different ambient dimensions
d = [50, 75, 100];
dLength = length(d);


%%%%%Rank of transition matrix
r = 4;

%%%%%Maximum iteration
kmax = 100;

%%%%%Repeated trials
T  = 100;

%%%%%Initialization
squaredErrorTensor = zeros(T, dLength, nLength);


%%%%%Parallel processing
parfor t = 1 : T
%%%%%Ordinary processing
% for t = 1 : T

    for in = 1 : nLength
        
        
        for j = 1 : dLength       
            
            %%%Construct low-rank matrix
            LL = randn(d(j), r);
            LR = randn(d(j), r);
            
            L = LL * LR';
            
            %%%%%Rescaling
            L = 0.9 * L / norm(L);
            
            %%%Construct AR process
            E = 1*eye(d(j)) * randn(d(j), n(j, in));
            
            x0 = zeros(d(j), 1);
            [Y, xStart] = ARProduce(x0, L, E, n(j, in));
            
            X = [xStart'; Y(:, 1: (n(j, in)-1))'];
                        
            %%%%%Initial point
            A0 = zeros(d(j), d(j));
            
            squaredError = PGD_Lowrank_ErrorScale(X, Y, A0, kmax, L);
            

            squaredErrorTensor(t, j, in) = squaredError;
            
        end
    end

end



squaredErrorAve = squeeze(sum(squaredErrorTensor, 1)) / T;

%%%%%Original squared estimation error vs. number of measurements
figure(1)
plot(n(1, :), squaredErrorAve(1, :), '-*','MarkerSize',6,'LineWidth',1.2);
hold on
plot(n(2, :), squaredErrorAve(2, :), '-o','MarkerSize',6,'LineWidth',1.2);
hold on
plot(n(3, :), squaredErrorAve(3, :), '-d','MarkerSize',6,'LineWidth',1.2);

xlabel('The number of samples $N$','fontsize',14,'interpreter','latex')
ylabel('Squared estimation error for \boldmath${\hat{\Gamma}}$','fontsize',14,'interpreter','latex')
legend('d = 50', 'd = 75', 'd = 100','fontsize',14);
axis tight

%%%%%Rescaled number of measurements
n1 = n(1, :) / (sqrt(6 * r * d(1)))^2;
n2 = n(2, :) / (sqrt(6 * r * d(2)))^2;
n3 = n(3, :) / (sqrt(6 * r * d(3)))^2;

%%%%%Squared estimation error vs. rescaled number of measurements
figure(2)

plot(n1, squaredErrorAve(1, :), '-*','MarkerSize',6,'LineWidth',1.2);
hold on
plot(n2, squaredErrorAve(2, :), '-o','MarkerSize',6,'LineWidth',1.2);
hold on
plot(n3, squaredErrorAve(3, :), '-d','MarkerSize',6,'LineWidth',1.2);

xlabel('The rescaled sample size $N / \omega(C_{L} \cap S_{F})^2$','fontsize',14,'interpreter','latex')
ylabel('Squared estimation error for \boldmath${\hat{\Gamma}}$','fontsize',14,'interpreter','latex')

legend('d = 50', 'd = 75', 'd = 100','fontsize',14);
axis tight


