% function producing simulation table for the coefficient regularisation.
% The output is a latex table stored in a text file with the name TableDGP
%
% Input:
% -DGPtype: selects the respective DGP for the VAR coefficient. For more
% details, see paper.
%           =1 for diagonal DGP
%           =2 for Diminishing diagonal DGP
%           =3 for random coefficent matrix
%           =4 for a netwok DGP
% The Simulation runs for N=[50 150 250]; T=[75 175 500];
% 
% Author: Ruben Hipp, 2021


function MasterRegNeo(DGPtype)
clearvars -except DGPtype kk
rng(1337)
curdict=cd;
addpath([curdict '/glmnet_matlab'])
addpath([curdict '/Functions'])
if isempty(gcp('nocreate'))==1
    parpool([4 24],'IdleTimeout',240)
end
pctRunOnAll warning('off','all')
addpath([curdict '/Graphical Lasso'])
addpath([curdict '/VariationalGarrotte'])
dbstop if error

%%
%Model Specifications
tic
DGPs = {'Diagonal','Diminishing-Diagonal','Random','Network'};
Type = DGPs{DGPtype};
target = 'FEVD';
AMethods = {'RIDGE','LASSO','AENET','Geometric'};
SigmaMethods = 'Sample-Cov';
deltas = 0.1:0.4:2.1;      %deltas for adaptive Thresholding
F = 100;                   %Parameters for elastic Net
N = [50 150 250];      %Dimension. Put array in here if output table is wished
T = [75 175 500];      %Timepoints. Put array in here if output table is wished
R = 500;               % Number of MC repetitions
DGPr = 25;             % Number of random draws of DGPs for DGP3
H = 10;                % Forecast horizon

% Main loop
n=0;
for Na=N
    n=n+1;
    t=0;
    for Ta=T
        t=t+1;
        if Ta>Na
            clear D
            
            for g=1:size(AMethods,2)
                tic
                clear OracleNormReg norms normPlotReg minReg
                Regularization.A = AMethods{g};
                Regularization.Sigma = SigmaMethods;
                
                dimension = [Na Ta R];
                density = 1/sqrt(Na);
                
                if DGPtype~=3
                    
                    [Y, real] = DGP(dimension,Type,density);
                    [oracleNorm, oraclenormStruct] = estimationA(Y,F,Regularization,deltas,real,target,H);
                    
                else
                    
                    dimension(3) = R/DGPr;
                    for r2=1:DGPr
                        [Y, realCof] = DGP(dimension,Type,density);
                        
                        [oracleNorm(:,r2), oracleNormStruct(:,r2)] = estimationA(Y,F,Regularization,deltas,realCof,target,H);
                    end
                    oracleNorm=mean(oracleNorm,2);
                    oraclenormStruct = mean(oracleNormStruct,2);
                end
                relOracleReg(n,t,g) = mean(oracleNorm);
                relOracleRegStruct(n,t,g) = mean(oraclenormStruct);
                disp([Regularization.A ' with N=' num2str(Na) ' took ' num2str(toc/60) ' minutes'])
            end
        end
    end
    
end

toc

%% Final Calculations and Latex table
[~,minInd]=min(relOracleReg,[],3);
isMin=zeros(size(relOracleReg));
for i=1:size(relOracleReg,2)
    for j=i:size(relOracleReg,1)
        isMin(i,j,minInd(i,j))=1;
    end
end
stackIsMin=[];
stackTable=[]; BeginningLine=['\textbf{\textit{DGP' num2str(DGPtype) '}}'];
for g=1:size(AMethods,2)
    Regularization.A=AMethods{g};
    BeginningLine=[BeginningLine '& \multicolumn{' num2str(length(N)) '}{c}{' Regularization.A '}'];
    stackTable=[stackTable round(relOracleReg(:,:,g),3)];
    stackIsMin=[stackIsMin isMin(:,:,g)];
    latex_tableReg=makeLatexTable(round(relOracleReg(:,:,g),3),N,T,isMin(:,:,g));
end

LatexTable = makeLatexTable(stackTable,N,repmat(T,1,size(AMethods,2)),stackIsMin);
LatexTable = [LatexTable(1:20+size(stackTable,2)) BeginningLine '\\' LatexTable(1+20+size(stackTable,2):end)]

if R > 200
    fid = fopen(['./Output/TableDGP' num2str(DGPtype) '.txt'],'wt');
    fprintf(fid, '%s\n%s\n%s', LatexTable);
    fclose(fid);
end

end