% min_X 0.5*mdot(X,C*X) + lambda*||X(:)||_0
clc;clear all;close all;
% warning off; maxNumCompThreads(1);
addpath('util','solver','../data');
rand('seed',0); randn('seed',0);


% time_list   = [10;20;30];
% data_list   = [1:12];
% r_list      = [20;50;100];
% lambda_list = [1;300;1000];


time_list   = [30];
data_list   = [1:12];
r_list      = [20];
lambda_list = [10;100;1000;10000];

result=[];


for i_time_list = 1:length(time_list)
    for i_lambda_list = 1:length(lambda_list)
        for i_r_list = 1:length(r_list)
            for i_data_list = 1:length(data_list)
                
                time_limit = time_list(i_time_list);
                idat = data_list(i_data_list);
                r = r_list(i_r_list);
                lambda = lambda_list(i_lambda_list);
                dat_x = GetData(idat);
                [m,n] = size(dat_x);
                
                C = - dat_x'*dat_x;
                fprintf('================= start =================\n');
                fprintf(' time_limit: %d\n',time_limit);
                fprintf('       data: %d\n',idat);
                fprintf('          r: %d\n',r);
                fprintf('     lambda: %d\n',lambda);
                fprintf('          m: %d\n',size(dat_x,1));
                fprintf('          n: %d\n',size(dat_x,2));
                fprintf('sparsity(I): %f\n',(r)/(n*r));
                X0 = eye(n,r);
                [X00, ~] = qr(randn(n,r), 0);
                %               X0 = RandomSparseOrth(n,r,i_data_list);
                
                HandleTrueObj = @(X)ComputeTrueObjL0PCA(X,C,lambda,1e-5);
                [X1] = ADMM_L0PCA(0.5*C,lambda,r,X0,1e7,time_limit,HandleTrueObj);
                fprintf('--- objective value:%.5f\n',HandleTrueObj(X1));
                [X2] = PADM_L0PCA(0.5*C,lambda,r,X0,1e7,time_limit,HandleTrueObj);
                fprintf('--- objective value:%.5f\n',HandleTrueObj(X2));
                [X3] = ADMM_L0PCA(0.5*C,lambda,r,X00,1e7,time_limit,HandleTrueObj);
                fprintf('--- objective value:%.5f\n',HandleTrueObj(X3));
                [X4] = PADM_L0PCA(0.5*C,lambda,r,X00,1e7,time_limit,HandleTrueObj);
                fprintf('--- objective value:%.5f\n',HandleTrueObj(X4));
                [X5] = OBCD(X0,C,lambda,HandleTrueObj(X1),1e7,1,time_limit,1e-8);
                fprintf('--- objective value:%.5f\n',HandleTrueObj(X5));
                
                fprintf('objective value:\n');
                fprintf('%.5f %.5f %.5f ',HandleTrueObj(X1),HandleTrueObj(X2),HandleTrueObj(X3));
                fprintf('%.5f %.5f %.5f ',HandleTrueObj(X4),HandleTrueObj(X5));
                fprintf('\n');
                
                fprintf('sparsity:\n');
                fprintf('%.5f %.5f %.5f ',sparsity(X1),sparsity(X2),sparsity(X3));
                fprintf('%.5f %.5f %.5f ',sparsity(X4),sparsity(X5));
                fprintf('\n');
                
                
                O = [];
                O.f1 = HandleTrueObj(X1);
                O.f2 = HandleTrueObj(X2);
                O.f3 = HandleTrueObj(X3);
                O.f4 = HandleTrueObj(X4);
                O.f5 = HandleTrueObj(X5);
                fprintf('%.2f & %.2f & %.2f & %.2f & %.2f \n',O.f1,O.f2,O.f3,O.f4,O.f5);
                result{i_time_list,i_lambda_list,i_r_list,i_data_list} = O;
                save result result;
            end
        end
    end
end



