% This program tests the submissions for Homework 3, AMSC 607 / CMSC 764
% Fall 2008.
% It generates a set of test problems and creates a vector, check,
% that gives the results of testing the linear programming optimality
% conditions for the solution returned by lpfeasdir.
%
% The definition of check is given in check_lp_opt.m. 
% Most importantly, the last entry is the time in seconds for the
% computation, and the entry before that is 0 if the optimality
% conditions are satisfied.
%

% The first 6 test problems were taken (with permission)
% from the program of Balaji Vasan Srinivasan.
% The last problem is designed to see whether the program is
% efficient, by seeing how long it takes on a large problem.

% The 6 test problems solve this problem:
%
% maximize x1-x2 
%
% subject to the constraints
%
% x1>=2,   x1<=4,   x2>=1,   x2<=3
% 
% Different starting points are used in the 6 test problems.

clc
clear all
close all
ncase = 0;
fid = fopen('outputfile','wt')
disp('Problem 1 - max x1-x2 subject to x1>=2,x1<=4,x2>=1,x2<=3');

% Defining the linear programming problem:
% max b'*x subject to A'*x>=c

A=[1 0; -1 0; 0 1; 0 -1]';
b=[1;-1];
c=[2;-4;1;-3];

% First case, start at the maximizer
disp(' ')
ncase = ncase + 1;
disp(sprintf('Case %d',ncase))
disp('Starting at the maximizer.')
fprintf(fid,'Starting at the maximizer.')
x=[4;1];
testoneproblem
%disp(sprintf('flag = %d',flag))

% Second case, start from a point inside the feasible region
disp(' ')
ncase = ncase + 1;
disp(sprintf('Case %d',ncase))
disp('Starting from a point inside the feasible region.')
fprintf(fid,'Starting from a point inside the feasible region.')
x=[3;2];
testoneproblem
%disp(sprintf('flag = %d',flag))

% Third case, start at the minimizer
disp(' ')
ncase = ncase + 1;
disp(sprintf('Case %d',ncase))
disp('Starting from a minimizer')
fprintf(fid,'Starting at the minimizer.')
x=[2;3];
testoneproblem
%disp(sprintf('flag = %d',flag))

% Fourth case, starting on a boundary
disp(' ')
ncase = ncase + 1;
disp(sprintf('Case %d',ncase))
disp('Starting on a boundary.')
fprintf(fid,'Starting on a boundary.')
x=[3;3];
testoneproblem
%disp(sprintf('flag = %d',flag))

%Fifth case, to check if the code works if one constraint is parallel to
%the function to be maximized, - here we maximize x1 subject to the same
%constraints

disp(' ')
ncase = ncase + 1;
disp(sprintf('Case %d',ncase))
disp('b is parallel to one of the constraints.')
fprintf(fid,'b parallel to a constraint.')
b=[1;0];
x=[3;2];
testoneproblem
%disp(sprintf('flag = %d',flag))

% Sixth case: Remove a constraint to make the solution unbounded.
% We remove the constraint x1<=4
disp(' ')
ncase = ncase + 1;
disp(sprintf('Case %d',ncase))
disp('Removing one of the constraints x1<=4 - solution unbounded.')
fprintf(fid,'Solution unbounded.')
A=[1 0; 0 1; 0 -1]';
b=[1;-1];
c=[2;1;-3];
x=[3;2];
tic
[x]=lpfeasdir(A,b,c,x);
check(7) = toc;
check(1:5)=0;
if (x(1)== Inf) & (x(2) == Inf)
   check(6)=0;
else
   check(6)=-111;
end
disp(sprintf('ncase=%d, check = %f %f %f %f %f %f %f',ncase,check))
fprintf(fid,'ncase=%d, check = %f %f %f %f %f %f %f \n',ncase,check)


% Seventh case: Test a large problem to see if the code is
% reasonably efficient.

disp(' ')
ncase = ncase + 1;
disp(sprintf('Case %d',ncase))
disp('Testing for efficiency using a large problem.')
fprintf(fid,'Testing a large problem.')
load ../myproblem
testoneproblem
xsav = x;

% Compare with Matlab's solver

disp(' ')
disp(sprintf('Case %d',ncase))
disp('Running Matlab solver linprog.')
fprintf(fid,'Running Matlab solver linprog.')
tic
x = linprog(-b,-A',-c);
mytime = toc;
check = check_lp_opt(A,b,c,x);
check(7) = mytime;
disp(sprintf('ncase=%d, check = %f %f %f %f %f %f %f',ncase,check))
fprintf(fid,'ncase=%d, check = %f %f %f %f %f %f %f \n',ncase,check)
lastcheck=norm(x-xsav);
disp(sprintf('Difference between lpfeasdir soln and linprog soln: %e',lastcheck))
fprintf(fid,'Difference between lpfeasdir soln and linprog soln: %e',lastcheck)



fclose(fid)
