% run_createFiles.m
% generate large sized test cases to really stress test your code
% once you have it working
rand('state',111);

% CONSTANTS
% Dimensions
minDim = 10;
maxDim = 200;
% Maximum and minimum values for random matrices the script generates.
minVal = 1;
maxVal = 1000;

% flags
outputFile = 1;
draw = 0;

% number of test cases
numSamples = 20;

% initialize data storage
% this is used to plot complexities
times.m         = zeros(1,numSamples);
times.n         = zeros(1,numSamples);
times.numItemsA = zeros(1,numSamples);
times.numItemsB = zeros(1,numSamples);
times.numItemsC = zeros(1,numSamples);
times.AaddnB    = zeros(1,numSamples);
times.AmultC    = zeros(1,numSamples);
times.Ascale    = zeros(1,numSamples);


% MAIN LOOP
for ti=1:numSamples

  % filenames
  fnA=sprintf('A_test_%d_large.txt',ti);
  fnB=sprintf('B_test_%d_large.txt',ti);
  fnC=sprintf('C_test_%d_large.txt',ti);
  fnAplusB=sprintf('A_addn_B_%d_large.txt',ti);
  fnAtimesC=sprintf('A_mult_C_%d_large.txt',ti);
  fnAscale=sprintf('A_mult_n_%d_large.txt',ti);

  % random values
  m=ceil(unifrnd(minDim-1,maxDim));
  n=ceil(unifrnd(minDim-1,maxDim));
  maxItemsA=ceil(unifrnd(0,m*n));
  maxItemsB=ceil(unifrnd(0,m*n));
  maxItemsC=ceil(unifrnd(0,m*n));
  scaleFac = round(rand*1000);

  times.m(ti)         = m;
  times.n(ti)         = n;
  
  [A,numItemsA] = createSparseMatrix(m,n,maxItemsA,minVal,maxVal);
  [B,numItemsB] = createSparseMatrix(m,n,maxItemsB,minVal,maxVal);
  [C,numItemsC] = createSparseMatrix(n,m,maxItemsC,minVal,maxVal);
  
  if outputFile
    outputSparseMatrix(A,m,n,fnA,numItemsA);
    outputSparseMatrix(B,m,n,fnB,numItemsB);
    outputSparseMatrix(C,n,m,fnC,numItemsC);
  end
  
  times.numItemsA(ti) = numItemsA;
  times.numItemsB(ti) = numItemsB;
  times.numItemsC(ti) = numItemsC;


  % Time each operation by surrounding it with 'tic' and 'toc'. This
  % is magic that Matlab provides.
  tic; tmp=A+B; times.AaddnB(ti)=toc;
  if outputFile
    outputSparseMatrix(tmp,m,n,fnAplusB,length(nonzeros(tmp)));
  end

  tic; tmp=A*C; times.AmultC(ti)=toc;
  if outputFile
    outputSparseMatrix(tmp,m,m,fnAtimesC,length(nonzeros(tmp)));
  end

  tic; tmp=scaleFac*A; times.Ascale(ti)=toc;
  if outputFile
    outputSparseMatrix(tmp,m,n,fnAscale,numItemsA,scaleFac);
  end

  % output progress every 10 iterations
  if ~(mod(ti,10))
    disp(sprintf('run_createLargeFiles.m: iteration %d completed',ti));
  end

end

% PLOTTING CODE
if draw
  % plot format settings
  linewidth = 3;
  fontsize = 14;
  markersize = 10;
  
  % PLOTS
  
  % Plot time(A+B, numItemsA, numItemsB), and also a regression line.
  figure(1)
  clf;
  hold on
  x1 = linspace(min(times.AaddnB),max(times.AaddnB),1000);
  p1 = polyfit(times.AaddnB,times.numItemsA+times.numItemsB,1);
  y1 = polyval(p1,x1);
  plot(y1, x1, 'r-', 'linewidth', linewidth, 'markersize', markersize);
  plot(times.numItemsA+times.numItemsB,times.AaddnB,'k.', 'linewidth', linewidth, 'markersize', markersize);
  % plot settings
  axis('tight');
  xlabel('numItemsA + numItemsB','fontsize',fontsize);
  ylabel('time(A+B) \mu sec','fontsize',fontsize);
  set(gca, 'LineWidth', linewidth);
  set(gca, 'FontSize', fontsize);
  
  % Plot time(n*A,numItemsA), and also a regression line.
  % Note that this is _linear_ in numItemsA, not constant.
  % You are required to implement this to work in constant time.
  figure(2)
  clf
  hold on
  x2 = linspace(min(times.Ascale),max(times.Ascale),1000);
  p2 = polyfit(times.Ascale,times.numItemsA,1);
  y2 = polyval(p2,x2);
  plot(y2,x2,'r-', 'linewidth', linewidth, 'markersize', markersize);
  plot(times.numItemsA,times.Ascale,'k.', 'linewidth', linewidth, 'markersize', markersize);
  % plot settings
  axis('tight');
  xlabel('numItemsA','fontsize',fontsize);
  ylabel('time(nA) \mu sec','fontsize',fontsize);
  set(gca, 'LineWidth', linewidth);
  set(gca, 'FontSize', fontsize);
  
  % Plot time(A*C, numItemsA, numItemsB). The resulting plot of this
  % isn't very clear because the complexity of this function is not a
  % simple linear function of numItemsA + numItemsB like the other 2.
  figure(3)
  clf
  hold on
  plot(times.numItemsA+times.numItemsB,times.AmultC,'k.', 'linewidth', linewidth, 'markersize', markersize);
  % plot settings
  axis('tight');
  xlabel('numItemsA+numItemsC','fontsize',fontsize);
  ylabel('time(AC) \mu sec','fontsize',fontsize);
  set(gca, 'LineWidth', linewidth);
  set(gca, 'FontSize', fontsize);
  
end
