%% Script used to generate Figure 7.1 
% Before running this, you should run the MaxCut experiment with all 
% datasets. This script only generates the figure from the saved results of
% these experiments. 

clearvars;

warning('off','MATLAB:dispatcher:UnresolvedFunctionHandle');

[G, DIMACS] = LoadData();

DataCombined = [G(:,1); DIMACS(:,1)];

MoSeK.cputime = [];
MoSeK.mem = [];

SDPT3.cputime = [];
SDPT3.mem = [];

SDPNAL.cputime = [];
SDPNAL.mem = [];

Sedumi.cputime = [];
Sedumi.mem = [];

CGAL.cputime = [];
CGAL.mem = [];

Failed.CGAL = {};
Failed.Sedumi = {};
Failed.SDPNAL = {};
Failed.SDPT3 = {};
Failed.MoSeK = {};
Failed.Manopt = {};

Dimensions = [];

for t = 1:size(G,1)

    dataName = ['G/',G{t,1}];
    fprintf([dataName,'\n'])
    
    n = G{t,2};
    Dimensions(end+1,1) = n; %#ok
    
    if exist(['../results/MaxCut/',dataName,'/MoSeK.mat'],'file')
        data.MoSeK = load(['../results/MaxCut/',dataName,'/MoSeK.mat']);
        MoSeK.cputime(end+1,1) = data.MoSeK.out.totalCpuTime;
        MoSeK.mem(end+1,1) = data.MoSeK.out.memory;
    else
        MoSeK.cputime(end+1,1) = nan;
        MoSeK.mem(end+1,1) = nan;
        Failed.MoSeK{end+1,1} = dataName;
    end
    
    if exist(['../results/MaxCut/',dataName,'/SDPNAL.mat'],'file')
        data.SDPNAL = load(['../results/MaxCut/',dataName,'/SDPNAL.mat']);
        if ~strcmp(data.SDPNAL.info.msg2,' SDP is not solved successfully')
            SDPNAL.cputime(end+1,1) = data.SDPNAL.out.totalCpuTime; 
            SDPNAL.mem(end+1,1) = data.SDPNAL.out.memory;
        else
            SDPNAL.cputime(end+1,1) = nan;
            SDPNAL.mem(end+1,1) = nan;
            Failed.SDPNAL{end+1,1} = dataName;
        end
    else
        SDPNAL.cputime(end+1,1) = nan;
        SDPNAL.mem(end+1,1) = nan;
        Failed.SDPNAL{end+1,1} = dataName;
    end
    
    if exist(['../results/MaxCut/',dataName,'/SDPT3.mat'],'file')
        data.SDPT3 = load(['../results/MaxCut/',dataName,'/SDPT3.mat']);
        SDPT3.cputime(end+1,1) = data.SDPT3.out.totalCpuTime; 
        SDPT3.mem(end+1,1) = data.SDPT3.out.memory;
    else
        SDPT3.cputime(end+1,1) = nan;
        SDPT3.mem(end+1,1) = nan;
        Failed.SDPT3{end+1,1} = dataName;
    end
    
    if exist(['../results/MaxCut/',dataName,'/Sedumi.mat'],'file')
        data.Sedumi = load(['../results/MaxCut/',dataName,'/Sedumi.mat']);
        Sedumi.cputime(end+1,1) = data.Sedumi.out.totalCpuTime;
        Sedumi.mem(end+1,1) = data.Sedumi.out.memory;
    else
        Sedumi.cputime(end+1,1) = nan;
        Sedumi.mem(end+1,1) = nan;
        Failed.Sedumi{end+1,1} = dataName;
    end
    
    if exist(['../results/MaxCut/',dataName,'/SketchyCGAL.mat'],'file')
        data.CGAL = load(['../results/MaxCut/',dataName,'/SketchyCGAL.mat']);
        data.CGAL.out.iteration(isnan(data.CGAL.out.iteration)) = [];
        pp = length(data.CGAL.out.iteration);
        if strcmp(data.CGAL.out.status,'stopping criteria met')
            CGAL.cputime(end+1,1) = data.CGAL.out.totalCpuTime;
            CGAL.mem(end+1,1) = data.CGAL.out.memory;
        else
            CGAL.cputime(end+1,1) = nan;
            CGAL.mem(end+1,1) = nan;
            Failed.CGAL{end+1,1} = dataName;
        end
    else
        CGAL.cputime(end+1,1) = nan;
        CGAL.mem(end+1,1) = nan;
        Failed.CGAL{end+1,1} = dataName;
    end
   
    
end


for t = 1:size(DIMACS,1)

    dataName = ['DIMACS10/',DIMACS{t,1}];
    fprintf([dataName,'\n'])
    
    n = DIMACS{t,2};
    Dimensions(end+1,1) = n; %#ok
    
    if exist(['../results/MaxCut/',dataName,'/Manopt.mat'],'file')
        data.Manopt = load(['../results/MaxCut/',dataName,'/Manopt.mat']);
        Manopt.cputime(end+1,1) = data.Manopt.out.totalCpuTime;
        Manopt.mem(end+1,1) = data.Manopt.out.memory;
    else
        Manopt.cputime(end+1,1) = nan;
        Manopt.mem(end+1,1) = nan;
        Failed.Manopt{end+1,1} = dataName;
    end
    
    if exist(['../results/MaxCut/',dataName,'/MoSeK.mat'],'file')
        data.MoSeK = load(['../results/MaxCut/',dataName,'/MoSeK.mat']);
        MoSeK.cputime(end+1,1) = data.MoSeK.out.totalCpuTime; 
        MoSeK.mem(end+1,1) = data.MoSeK.out.memory;
    else
        MoSeK.cputime(end+1,1) = nan;
        MoSeK.mem(end+1,1) = nan;
        Failed.MoSeK{end+1,1} = dataName;
    end
    
    if exist(['../results/MaxCut/',dataName,'/SDPNAL.mat'],'file')
        data.SDPNAL = load(['../results/MaxCut/',dataName,'/SDPNAL.mat']);
        if ~strcmp(data.SDPNAL.info.msg2,' SDP is not solved successfully')
            SDPNAL.cputime(end+1,1) = data.SDPNAL.out.totalCpuTime; 
            SDPNAL.mem(end+1,1) = data.SDPNAL.out.memory;
        else
            SDPNAL.cputime(end+1,1) = nan;
            SDPNAL.mem(end+1,1) = nan;
            Failed.SDPNAL{end+1,1} = dataName;
        end
    else
        SDPNAL.cputime(end+1,1) = nan;
        SDPNAL.mem(end+1,1) = nan;
        Failed.SDPNAL{end+1,1} = dataName;
    end

    
    if exist(['../results/MaxCut/',dataName,'/SDPT3.mat'],'file')
        data.SDPT3 = load(['../results/MaxCut/',dataName,'/SDPT3.mat']);
        SDPT3.cputime(end+1,1) = data.SDPT3.out.totalCpuTime; 
        SDPT3.mem(end+1,1) = data.SDPT3.out.memory;
    else
        SDPT3.cputime(end+1,1) = nan;
        SDPT3.mem(end+1,1) = nan;
        Failed.SDPT3{end+1,1} = dataName;
    end
    
    if exist(['../results/MaxCut/',dataName,'/Sedumi.mat'],'file')
        data.Sedumi = load(['../results/MaxCut/',dataName,'/Sedumi.mat']);
        Sedumi.cputime(end+1,1) = data.Sedumi.out.totalCpuTime;
        Sedumi.mem(end+1,1) = data.Sedumi.out.memory;
    else
        Sedumi.cputime(end+1,1) = nan;
        Sedumi.mem(end+1,1) = nan;
        Failed.Sedumi{end+1,1} = dataName;
    end
    
    if exist(['../results/MaxCut/',dataName,'/SketchyCGAL.mat'],'file')
        data.CGAL = load(['../results/MaxCut/',dataName,'/SketchyCGAL.mat']);
        data.CGAL.out.iteration(isnan(data.CGAL.out.iteration)) = [];
        pp = length(data.CGAL.out.iteration);
        if strcmp(data.CGAL.out.status,'stopping criteria met')
            CGAL.cputime(end+1,1) = data.CGAL.out.totalCpuTime;
            CGAL.mem(end+1,1) = data.CGAL.out.memory;
        else
            CGAL.cputime(end+1,1) = nan;
            CGAL.mem(end+1,1) = nan;
            Failed.CGAL{end+1,1} = dataName;
        end
    else
        CGAL.cputime(end+1,1) = nan;
        CGAL.mem(end+1,1) = nan;
        Failed.CGAL{end+1,1} = dataName;
    end
   
    
end

%% Delete the problems where all solvers have failed!

inds2del = isnan(CGAL.mem) ...
    & isnan(MoSeK.mem) ...
    & isnan(SDPT3.mem) ...
    & isnan(SDPNAL.mem) ...
    & isnan(Sedumi.mem) ...
    & isnan(Manopt.mem);

FailedProblemDimensions = Dimensions(inds2del);
Dimensions(inds2del) = [];
DataCombined(inds2del) = [];
fields = fieldnames(CGAL);
for t = 1:numel(fields)
  CGAL.(fields{t})(inds2del) = [];
end
fields = fieldnames(MoSeK);
for t = 1:numel(fields)
  MoSeK.(fields{t})(inds2del) = [];
end
fields = fieldnames(SDPT3);
for t = 1:numel(fields)
  SDPT3.(fields{t})(inds2del) = [];
end
fields = fieldnames(SDPNAL);
for t = 1:numel(fields)
  SDPNAL.(fields{t})(inds2del) = [];
end
fields = fieldnames(Sedumi);
for t = 1:numel(fields)
  Sedumi.(fields{t})(inds2del) = [];
end

%% Plot the graph
hfig1 = figure('Position',[100,100,600,320]);
set(hfig1,'name','MaxCut-StorageVsSize','numbertitle','off');
hold on;
hsc1 = scatter(Dimensions,CGAL.mem,100,'filled','Marker','o');
hsc2 = scatter(Dimensions,Sedumi.mem,100,'filled','Marker','o');
hsc3 = scatter(Dimensions,SDPT3.mem,100,'filled','Marker','o');
hsc4 = scatter(Dimensions,MoSeK.mem,100,'filled','Marker','o');
hsc5 = scatter(Dimensions,SDPNAL.mem,100,'filled','Marker','o');

hslc1 = plot(nan,nan,'LineStyle','none','Marker','o','MarkerSize',8,'MarkerEdgeColor',hsc1.MarkerEdgeColor,'MarkerFaceColor',hsc1.CData);
hslc2 = plot(nan,nan,'LineStyle','none','Marker','o','MarkerSize',8,'MarkerEdgeColor',hsc2.MarkerEdgeColor,'MarkerFaceColor',hsc2.CData);
hslc3 = plot(nan,nan,'LineStyle','none','Marker','o','MarkerSize',8,'MarkerEdgeColor',hsc3.MarkerEdgeColor,'MarkerFaceColor',hsc3.CData);
hslc4 = plot(nan,nan,'LineStyle','none','Marker','o','MarkerSize',8,'MarkerEdgeColor',hsc4.MarkerEdgeColor,'MarkerFaceColor',hsc4.CData);
hslc5 = plot(nan,nan,'LineStyle','none','Marker','o','MarkerSize',8,'MarkerEdgeColor',hsc5.MarkerEdgeColor,'MarkerFaceColor',hsc5.CData);

alpha(0.6);
hl= legend([hslc2,hslc3,hslc4,hslc5,hslc1],...
    'SEDUMI','SDPT3','MOSEK','SDPNAL+','CGAL');
hl.Interpreter = 'latex';
hl.FontSize = 14;
hl.Location = 'SouthEast';

ax = gca;
ax.XScale = 'log';
ax.YScale = 'log';
grid on
xlim([7e2,9e6]);
ylim([4,23500]);

set(gca,'TickDir','out')
set(gca,'LineWidth',1,'TickLength',[0.02 0.02]);

ax.YTick = [4,16,64,256,1024,4096,16384];
ax.XTick = 10.^(-10:10);
ax.YTickLabel = {'4 MB','16 MB','64MB','256MB','1GB','4GB','16GB'};
ax.TickLabelInterpreter = 'latex';
ax.FontSize = 14;
ax.Box = 'on';

ax.YRuler.MinorTick = 'off';

ylabel('storage','Interpreter','latex','FontSize',16);
xlabel('problem size: $n$','Interpreter','latex','FontSize',16);

grid on, grid minor;

%% Plot the graph
hfig2 = figure('Position',[100,100,600,320]);
set(hfig2 ,'name','MaxCut-TimeVsSize','numbertitle','off');
hold on;
hsc1 = scatter(Dimensions,CGAL.cputime,100,'filled','Marker','o');
hsc2 = scatter(Dimensions,Sedumi.cputime,100,'filled','Marker','o');
hsc3 = scatter(Dimensions,SDPT3.cputime,100,'filled','Marker','o');
hsc4 = scatter(Dimensions,MoSeK.cputime,100,'filled','Marker','o');
hsc5 = scatter(Dimensions,SDPNAL.cputime,100,'filled','Marker','o');

alpha(0.6);

ax = gca;
ax.XScale = 'log';
ax.YScale = 'log';
grid on
axis tight;
xlim([7e2,9e6]);

set(gca,'TickDir','out')
set(gca,'LineWidth',1,'TickLength',[0.02 0.02]);

ax.YTick = 10.^(-10:10);
ax.XTick = 10.^(-10:10);
ax.TickLabelInterpreter = 'latex';
ax.FontSize = 14;
ax.Box = 'on';

ax.YRuler.MinorTick = 'off';

ylabel('cpu time (sec)','Interpreter','latex','FontSize',16);
xlabel('problem size: $n$','Interpreter','latex','FontSize',16);

grid on, grid minor;

%% FUNCTION TO LOAD DATANAMES AND SIZES
function [G, DIMACS] = LoadData

G = {'G1',800;...
    'G2',800;...
    'G3',800;...
    'G4',800;...
    'G5',800;...
    'G6',800;...
    'G7',800;...
    'G8',800;...
    'G9',800;...
    'G10',800;...
    'G11',800;...
    'G12',800;...
    'G13',800;...
    'G14',800;...
    'G15',800;...
    'G16',800;...
    'G17',800;...
    'G18',800;...
    'G19',800;...
    'G20',800;...
    'G21',800;...
    'G22',2000;...
    'G23',2000;...
    'G24',2000;...
    'G25',2000;...
    'G26',2000;...
    'G27',2000;...
    'G28',2000;...
    'G29',2000;...
    'G30',2000;...
    'G31',2000;...
    'G32',2000;...
    'G33',2000;...
    'G34',2000;...
    'G35',2000;...
    'G36',2000;...
    'G37',2000;...
    'G38',2000;...
    'G39',2000;...
    'G40',2000;...
    'G41',2000;...
    'G42',2000;...
    'G43',1000;...
    'G44',1000;...
    'G45',1000;...
    'G46',1000;...
    'G47',1000;...
    'G48',3000;...
    'G49',3000;...
    'G50',3000;...
    'G51',1000;...
    'G52',1000;...
    'G53',1000;...
    'G54',1000;...
    'G55',5000;...
    'G56',5000;...
    'G57',5000;...
    'G58',5000;...
    'G59',5000;...
    'G60',7000;...
    'G61',7000;...
    'G62',7000;...
    'G63',7000;...
    'G64',7000;...
    'G65',8000;...
    'G66',9000;...
    'G67',10000};

DIMACS = {'144',144649;...
    '333SP',3712815;...
    '598a',110971;...
    'adaptive',6815744;...
    'ak2010',45292;...
    'al2010',252266;...
    'ar2010',186211;...
    'AS365',3799275;...
    'asia_osm',11950757;...
    'auto',448695;...
    'az2010',241666;...
    'belgium_osm',1441295;...
    'ca2010',710145;...
    'caidaRouterLevel',192244;...
    'channel-500x100x100-b050',4802000;...
    'chesapeake',39;...
    'citationCiteseer',268495;...
    'co2010',201062;...
    'coAuthorsCiteseer',227320;...
    'coAuthorsDBLP',299067;...
    'coPapersCiteseer',434102;...
    'coPapersDBLP',540486;...
    'cs4',22499;...
    'ct2010',67578;...
    'cti',16840;...
    'data',2851;...
    'de2010',24115;...
    'delaunay_n10',1024;...
    'delaunay_n11',2048;...
    'delaunay_n12',4096;...
    'delaunay_n13',8192;...
    'delaunay_n14',16384;...
    'delaunay_n15',32768;...
    'delaunay_n16',65536;...
    'delaunay_n17',131072;...
    'delaunay_n18',262144;...
    'delaunay_n19',524288;...
    'delaunay_n20',1048576;...
    'delaunay_n21',2097152;...
    'delaunay_n22',4194304;...
    'delaunay_n23',8388608;...
    'delaunay_n24',16777216;...
    'europe_osm',50912018;...
    'fe_4elt2',11143;...
    'fe_body',45087;...
    'fe_ocean',143437;...
    'fe_rotor',99617;...
    'fe_sphere',16386;...
    'fe_tooth',78136;...
    'fl2010',484481;...
    'G_n_pin_pout',100000;...
    'ga2010',291086;...
    'germany_osm',11548845;...
    'great-britain_osm',7733822;...
    'hi2010',25016;...
    'hugebubbles-00000',18318143;...
    'hugebubbles-00010',19458087;...
    'hugebubbles-00020',21198119;...
    'hugetrace-00000',4588484;...
    'hugetrace-00010',12057441;...
    'hugetrace-00020',16002413;...
    'hugetric-00000',5824554;...
    'hugetric-00010',6592765;...
    'hugetric-00020',7122792;...
    'ia2010',216007;...
    'id2010',149842;...
    'il2010',451554;...
    'in2010',267071;...
    'italy_osm',6686493;...
    'kron_g500-logn16',65536;...
    'kron_g500-logn17',131072;...
    'kron_g500-logn18',262144;...
    'kron_g500-logn19',524288;...
    'kron_g500-logn20',1048576;... % what about 21?
    'kron_g500-logn21',2097152;...
    'ks2010',238600;...
    'ky2010',161672;...
    'la2010',204447;...
    'luxembourg_osm',114599;...
    'm14b',214765;...
    'M6',3501776;...
    'ma2010',157508;...
    'md2010',145247;...
    'me2010',69518;...
    'mi2010',329885;...
    'mn2010',259777;...
    'mo2010',343565;...
    'ms2010',171778;...
    'mt2010',132288;...
    'NACA0015',1039183;...
    'nc2010',288987;...
    'nd2010',133769;...
    'ne2010',193352;...
    'netherlands_osm',2216688;...
    'nh2010',48837;...
    'nj2010',169588;...
    'NLR',4163763;...
    'nm2010',168609;...
    'nv2010',84538;...
    'ny2010',350169;...
    'oh2010',365344;...
    'ok2010',269118;...
    'or2010',196621;...
    'pa2010',421545;...    
    'packing-500x100x100-b050',2145852;...
    'preferentialAttachment',100000;...
    'rgg_n_2_15_s0',32768;...
    'rgg_n_2_16_s0',65536;...
    'rgg_n_2_17_s0',131072;...
    'rgg_n_2_18_s0',262144;...
    'rgg_n_2_20_s0',1048576;...
    'rgg_n_2_21_s0',2097152;...
    'rgg_n_2_22_s0',4194304;...
    'rgg_n_2_23_s0',8388608;...
    'rgg_n_2_24_s0',16777216;...
    'ri2010',25181;...
    'road_central',14081816;...
    'road_usa',23947347;...
    'sc2010',181908;...
    'sd2010',88360;...
    'smallworld',100000;...
    't60k',60005;...
    'tn2010',240116;...
    'tx2010',914231;...
    'uk',4824;...
    'ut2010',115406;...
    'va2010',285762;...
    'venturiLevel3',4026819;...
    'vsp_barth5_1Ksep_50in_5Kout',32212;...
    'vsp_bcsstk30_500sep_10in_1Kout',58348;...
    'vsp_befref_fxm_2_4_air02',14109;...
    'vsp_bump2_e18_aa01_model1_crew1',56438;...
    'vsp_c-30_data_data',11023;...
    'vsp_c-60_data_cti_cs4',85830;...
    'vsp_data_and_seymourl',9167;...
    'vsp_finan512_scagr7-2c_rlfddd',139752;...
    'vsp_mod2_pgp2_slptsk',101364;...
    'vsp_model1_crew1_cr42_south31',45101;...
    'vsp_msc10848_300sep_100in_1Kout',21996;...
    'vsp_p0291_seymourl_iiasa',10498;...
    'vsp_sctap1-2b_and_seymourl',40174;...
    'vsp_south31_slptsk',39668;...
    'vsp_vibrobox_scagr7-2c_rlfddd',77328;...
    'vt2010',32580;...
    'wa2010',195574;...
    'wi2010',253096;...
    'wing',62032;...
    'wing_nodal',10937;...
    'wv2010',135218;...
    'wy2010',86204};

end

%% Last edit: Alp Yurtsever - December 2, 2019
