function testjsr(varargin)
% testjsr('what', dim, N, [options])
% Compares various algorithms to compute the JSR.
% In particular these are: Gripenberg, modified invariant polytope, conitope, pathcomplete, sos, max-relaxation, linear-relaxation and semidefinite-lifting.
%
% Input:
%   'what'          string passed to tgallery
%   dim             2nd value passed to tgallery
%   N               3rd value passed to tgallery
%   'delta',val     relative accuracy to search for. Default=0.95
%
% Output:
%   Nice pictures
%
% See also: jsr, testtjsr, findsmp, jsr, jsr_norm_conitope, jsr_pathcomplete, jsr_opti_sos, jsr_lift_semidefinite
%
% Written by: tommsch, 2017

%#ok<*AGROW>

N=varargin{3};      varargin(3)=[];
dim=varargin{2};    varargin(2)=[];
what=varargin{1};   varargin(1)=[];
[delta,varargin]=parsem('delta',varargin,0.95);

seed=1000;

while(true)
    
    figidx=randi(10000000);
    f = figure(figidx);

    k=0;
    
    JSR=[];
    time_tjsr=[];
    time_gripenberg=[];
    time_conitope=[];
    time_pathcomplete=[];
    time_sos=[];
    time_mr=[];
    time_lr=[];
    time_semi=[];
    
    while(true)
        
        maxtime=2^dim+60;
        seed=seed+1;
        
        cprintf('err','Seed = %i\n',seed);
        if(k > 30); 
            break; 
        end;

        M=tgallery(what,dim,N,seed);
            
%        tjsr
%         try
            [ JSR, ret_tjsr]=tjsr(M,'maxtime',maxtime,'verbose',1,'delta',delta,varargin{:});            
%         catch
%             continue;
%         end
        if(isempty(ret_tjsr.info.algorithm)); continue; end;
        if(ret_tjsr.info.algorithm==2); continue; end;
        if(length(JSR)==1); JSR=[JSR JSR]; end;
        oo=ret_tjsr.cyclictree.ordering{1};
        time_tjsr(end+1)=ret_tjsr.counter.treetime;
        


        %gripenberg
        fprintf('GRIPENBERG:\n');
        eps_grip=(1/delta);
        tic;
        while(true)
            [ ~, ~, ret_gripenberg]=findsmp(M,'gripenberg','delta',1-eps_grip,'maxsmpdepth',inf,'verbose',2,'maxtime',maxtime);
            if(ret_gripenberg.jsrbound(1)/ret_gripenberg.jsrbound(2)<delta); break; else; eps_grip=eps_grip/2; end;
            if(toc>maxtime); ret_gripenberg.elapsedtime=inf; break; end;
        end
        time_gripenberg(end+1)=ret_gripenberg.time;

        %conitope       
        fprintf('CONITOPE:\n');
        eps_conitope=(1/delta);
        tic;
        while(true)
            opts_conitope = jsrsettings('conitope.tol',eps_conitope,'conitope.initProd',oo,'conitope.maxiter',60);
            [~,~,~,ret_conitope]=jsr_norm_conitope(M,opts_conitope);
            if(min(ret_conitope.allUb)/JSR(1)-1<1-delta); break; else; eps_conitope=eps_conitope/2; end; 
            if(toc>maxtime); ret_conitope.elapsedtime=inf; break; end;
        end;
        time_conitope(end+1)=ret_conitope.elapsedtime;

        %lift
        tic;
        fprintf('SEMIDEFLIFT:\n');
        numlifts_semi=3*dim;
        
        opts_semi = jsrsettings('semidef.maxDepth',numlifts_semi);
        [~,ret_semi]=jsr_lift_semidefinite(M,opts_semi);
        if(min(ret_semi.allUb)/JSR(1)-1<1-delta); else; ret_semi.elapsedtime=inf;  end;
        time_semi(end+1)=ret_semi.elapsedtime; 

        %pathcomplete
        tic;
        fprintf('PATHCOMPLETE:\n');
        eps_pathcomplete=(1/delta);
        debrujindim=1;
        while(true)
            opts_pathcomplete = jsrsettings('pathcomplete.reltol',eps_pathcomplete,'debruijn.dimension',debrujindim,'pathcomplete.maxiter',maxtime);
            [~,~,ret_pathcomplete]=jsr_pathcomplete(M,opts_pathcomplete);
            if(ret_pathcomplete.bisec(2)/JSR(1)-1<1-delta); break; else; eps_pathcomplete=eps_pathcomplete/2; debrujindim=debrujindim+1; end;
            if(toc>maxtime); ret_pathcomplete.elapsedtime=inf; break; end;
        end;
        time_pathcomplete(end+1)=ret_pathcomplete.elapsedtime; 
        
%         tic;
        fprintf('SOS:\n');
        eps_sos=(1/delta);
        maxiter_sos=maxtime+1000;
        deg_sos=1;
        counter_sos=1;
        while(true)
            opts_sos = jsrsettings('sos.tol',eps_sos,'sos.maxiter',maxtime+1000,'sos.deg',deg_sos);
            [~,~,ret_sos]=jsr_opti_sos(M,opts_sos);
            if(ret_sos.bissec(2)/JSR(1)-1<1-delta); break; end;
            if(toc>maxtime || counter_sos>3 ); ret_sos.elapsedtime=inf; break; end;
            
            counter_sos=counter_sos+1;
            eps_sos=eps_sos/2;  
            maxiter_sos=maxiter_sos*2; 
        end;
        time_sos(end+1)=ret_sos.elapsedtime;
        
        % MAXRELAX AND LINRELAX GIVE WRONG VALUES!!!!!!
         fprintf('\n\n=======================\n');
         eps_mr=(1/delta);
         while(true)
             fprintf('MAXRELAXATION:\n');
             opts_mr = jsrsettings('maxrel.tol',eps_mr,'maxrel.maxiter',maxtime+500);
             [~,ret_mr]=jsr_norm_maxRelaxation(M,opts_mr);
             if(min(ret_mr.allUb)/JSR(1)-1<1-delta); break; else; eps_mr=eps_mr/2;  end;
         end;
         time_mr(end+1)=ret_mr.elapsedtime;
         
         fprintf('\n\n=====================\n');
         eps_lr=(1/delta);
         while(true)
             fprintf('LINEAR RELAXATION 2D:\n');
             opts_lr = jsrsettings('linrel.tol',eps_lr,'linrel.maxiter',maxtime+500);
             [~,ret_lr]=jsr_norm_maxRelaxation(M,opts_lr);
             if(min(ret_lr.allUb)/JSR(1)-1<1-delta); break; else; eps_lr=eps_lr/2;  end;
         end;
         time_lr(end+1)=ret_lr.elapsedtime;
        
        figure(figidx)
        semilogy([time_tjsr; time_gripenberg; time_conitope; time_semi; time_pathcomplete; time_sos; time_mr; time_lr]','x-');
        titlestring=[what ', N:' num2str(N) ', dim: ' num2str(dim) ', delta: ' num2str(delta) ', time: ' datestr(now,'yyyy-mm-dd-HH-MM-SS')];
        title(titlestring);
        legend(...
            ['tjsr (' num2str(min(time_tjsr)) ' - '         num2str(mean(time_tjsr)) ' - '          num2str(max(time_tjsr)) ')' ],...
            ['grip (' num2str(min(time_gripenberg)) ' - '   num2str(mean(time_gripenberg)) ' - '    num2str(max(time_gripenberg)) ')' ],...
            ['cone (' num2str(min(time_conitope)) ' - '     num2str(mean(time_conitope)) ' - '      num2str(max(time_conitope)) ')' ],...
            ['semi (' num2str(min(time_semi)) ' - '         num2str(mean(time_semi)) ' - '          num2str(max(time_semi)) ')' ],...
            ['path (' num2str(min(time_pathcomplete)) ' - ' num2str(mean(time_pathcomplete)) ' - '  num2str(max(time_pathcomplete)) ')' ],...
            ['sos  (' num2str(min(time_sos)) ' - '          num2str(mean(time_sos)) ' - '           num2str(max(time_sos)) ')' ], ...
            ['mr   (' num2str(min(time_mr)) ' - '          num2str(mean(time_mr)) ' - '           num2str(max(time_mr)) ')' ], ...
            ['lr   (' num2str(min(time_lr)) ' - '          num2str(mean(time_lr)) ' - '           num2str(max(time_lr)) ')' ] ...
            );
            
        drawnow
        
        k=k+1;
        
            print(f,['testjsr: ' titlestring],'-dpng')

    end
    
    dim=dim+1;

end




end


  


function dummy; end %#ok<DEFNU> %Generates an error, if the 'end' of a function is missing. 
