function demo_orth
clc;clear all;close all;
addpath('solver','util','data');
rand('seed',1); randn('seed',1);

timeLimit_list = [5 5 5 5 5 5 10 5];
data_list      = [1 2 3 4 5 6 7 8 ];
r_list         = [20 50];

position_list1 = {'NorthEast','NorthEast','NorthEast','NorthEast','NorthEast','NorthEast','NorthEast','NorthEast'};
position_list2 = {'NorthEast','NorthEast','NorthEast','NorthEast','NorthEast','NorthEast','NorthEast','NorthEast'};

 
for i_r_list = 1:length(r_list)
    
    for i_data_list = 1:length(data_list)
        timeLimit = timeLimit_list(i_data_list);
        idat = data_list(i_data_list);
        
                if(i_r_list==1)
            position = position_list1{i_data_list};
        else
            position = position_list2{i_data_list};
                end

     
        dat_r = r_list(i_r_list);
        A = GetData2(idat);
        [dat_m,dat_n] = size(A);
        X0 = OrthProj(randn(dat_n,dat_r));
        HandleObjSmooth = @(X)ComputeObjGrad(X,A);
        HandleObjNonSmooth = @(X)0;
        HandleObjF = @(X)HandleObjSmooth(X) + HandleObjNonSmooth(X);
        HandleProx = @(a,theta)GenProximalMappingOrth(a,theta);
        timeIntervel = timeLimit/15;
        maxiter = 1e10;
        
        
        
        opts=[];
        opts.mxitr  = maxiter;
        opts.timeLimit = timeLimit;
        opts.timeIntervel = timeIntervel;
        opts.retr = 0;
        [X1,fobjs1,ts1] = OptStiefelGBB(X0,HandleObjSmooth,opts);
        
        opts=[];
        opts.mxitr  = maxiter;
        opts.timeLimit = timeLimit;
        opts.timeIntervel = timeIntervel;
        opts.retr = 1;
        [X2,fobjs2,ts2] = OptStiefelGBB(X0,HandleObjSmooth,opts);
        
        [X3,fobjs3,ts3] = AccerlatedProximalGradientBacktracking(X0,HandleObjSmooth,HandleObjNonSmooth,HandleProx,maxiter,timeLimit,timeIntervel);
        
        
        
        opts = [];  opts.info = 0; opts.gtol = 1e-5; opts.solver = 1;
        [X4,fobjs4,ts4] = FOForth(X0,zeros(size(X0)),timeLimit,timeIntervel,HandleObjSmooth,opts);
        
        opts = [];  opts.info = 0; opts.gtol = 1e-5; opts.solver = 2;
        [X5,fobjs5,ts5] = FOForth(X0,zeros(size(X0)),timeLimit,timeIntervel,HandleObjSmooth,opts);
        
        opts = [];  opts.info = 0; opts.gtol = 1e-5; opts.solver = 3;
        [X6,fobjs6,ts6] = FOForth(X0,zeros(size(X0)),timeLimit,timeIntervel,HandleObjSmooth,opts);
        
        
        fobj_ref = 0;
        [X7,fobjs7,ts7] = AEPG(X0,HandleObjSmooth,HandleObjNonSmooth,HandleProx,timeLimit,timeIntervel,0.0,fobj_ref);
        [X8,fobjs8,ts8] = AEPG(X0,HandleObjSmooth,HandleObjNonSmooth,HandleProx,timeLimit,timeIntervel,0.1,fobj_ref);
        [X9,fobjs9,ts9] = AEPG(X0,HandleObjSmooth,HandleObjNonSmooth,HandleProx,timeLimit,timeIntervel,0.5,fobj_ref);
        [X10,fobjs10,ts10] = AEPG(X0,HandleObjSmooth,HandleObjNonSmooth,HandleProx,timeLimit,timeIntervel,0.9,fobj_ref);
        
        [fobjs1,fobjs2,fobjs3,fobjs4,fobjs5,fobjs6,fobjs7,fobjs8,fobjs9,fobjs10] = normF(fobjs1,fobjs2,fobjs3,fobjs4,fobjs5,fobjs6,fobjs7,fobjs8,fobjs9,fobjs10);
        
        close all;
        pause(0.01)
        pcolor = loadcolor10;
        myplot = @semilogy;
        % : ²»ΊΓ
        myplot(ts1,fobjs1,'-'  ,'LineWidth',3,'MarkerSize',3,'color', pcolor.teal);  hold on;
        myplot(ts2,fobjs2,'-'   ,'LineWidth',3,'MarkerSize',3,'color', pcolor.lime );  hold on;
        myplot(ts3,fobjs3,'-'   ,'LineWidth',3,'MarkerSize',3,'color', pcolor.skyblue); hold on;
        myplot(ts4,fobjs4,'-'  ,'LineWidth',3,'MarkerSize',3,'color', pcolor.gold);    hold on;
        myplot(ts5,fobjs5,'-'   ,'LineWidth',3,'MarkerSize',3,'color', pcolor.lavender);  hold on;
        myplot(ts6,fobjs6,'-'   ,'LineWidth',3,'MarkerSize',3,'color', pcolor.olive);    hold on;
        myplot(ts7,fobjs7,'-'   ,'LineWidth',3,'MarkerSize',3,'color', pcolor.turquoise);   hold on;
        myplot(ts8,fobjs8,'-'   ,'LineWidth',3,'MarkerSize',3,'color', pcolor.mustard);     hold on;
        myplot(ts9,fobjs9,'-'   ,'LineWidth',3,'MarkerSize',3,'color', pcolor.plum);     hold on;
        myplot(ts10,fobjs10,'-' ,'LineWidth',3,'MarkerSize',3,'color', pcolor.coral);     hold on;
        
        hleg= legend('OptM-QR','OptM-Cayley','APG','FOForth-GR','FOForth-P','FOForth-QR','AEPG(0)','AEPG(0.1)','AEPG(0.5)','AEPG(0.9)', 'Interpreter', 'latex');
        
        set(hleg,'FontSize',13,'FontWeight','normal');
        set(hleg,'Fontname','times new Roman');
        %         set(hleg,'Location','NorthEast');
%         set(hleg,'Location','SouthWest');
        set(hleg,'Location',position);
        set(gca,'Fontsize', 12);
        set(hleg, 'Color', 'none');
        xlabel('Time (seconds)','FontSize',12)
        ylabel('Relative Objective','FontSize',12,'interpreter','latex')
        
        all_fobj = [fobjs1;fobjs2;fobjs3;fobjs4;fobjs5;fobjs6;fobjs7;fobjs8;fobjs9;fobjs10];
        axis([0,timeLimit+1,min(all_fobj),max(all_fobj)]);
        fprintf('\n');
        set(gcf,'paperpositionmode','auto')
        print(sprintf('%s_%d_%d.eps',mfilename,i_r_list,idat),'-depsc2','-loose');
        print(sprintf('%s_%d_%d.png',mfilename,i_r_list,idat),'-dpng');
        %     print(sprintf('%s_%d.pdf',mfilename,iwhich),'-dpdf', '-r0');
        
    end
end








function [fobj,grad] = ComputeObjGrad(X,A)
% min_X  ||A*X*X' - A||_F^2
% A: m x n
% X: x x r
AX = A*X;
fobj = norm(A,'fro')^2 - mdot(AX,AX);  % equivalent to norm(A*X*X'-A,'fro')^2
if(nargout>1)
    grad = -2*A'*AX;
end


function [X,fobjs,ts] = AEPG(X,hObjSmooth,hObjNonSmooth,hProx,timeLimit,timeIntervel,theta,f0)

hObjF = @(X)hObjSmooth(X)+hObjNonSmooth(X);
initt = clock;
last_rec_clock = initt;
ts = []; fobjs = [];
fobjs = [fobjs;hObjF(X)];
ts = [ts;etime(clock,initt)];

v = 1e-3;
Y = X;
sigma = theta;

for iter = 1:100000000
    
    [~,grad] = hObjSmooth(Y);
    Xt = X;
    X = hProx(Y-grad/v,v);
    Diff = X - Xt;
    alpha = 1e-3;
    r = v*Diff;
    s = alpha*norm(r,'fro')^2;
    v_old = v;
    v = sqrt(v*v + s);
    sigma = theta*(1-sigma)*v_old/v;
    Y = X + sigma*Diff;
    
    % compute statistics
    cur_clock = clock;
    if(etime(cur_clock,last_rec_clock) > timeIntervel)
        F = hObjF(X);
        fprintf('iter:%d, diff:%.2e, v:%.2e, F-F*: %.4e\n',...
            iter,norm(Diff,'fro'),v,F-f0);
        ElasTime =  etime(cur_clock,initt);
        fobjs  = [fobjs;F];
        ts = [ts;ElasTime];
        last_rec_clock = cur_clock;
        if ElasTime > timeLimit
            break;
        end
    end
end
