Skip to content

Commit

Permalink
Fix for links and instructions for testing warnings
Browse files Browse the repository at this point in the history
Fix for gurobi - QP

Fix for gurobi variables

Fix for OS compatibility in retrieveModels

Fix for global variables
  • Loading branch information
laurentheirendt committed Apr 20, 2017
1 parent 89616da commit 24b38d6
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 75 deletions.
14 changes: 11 additions & 3 deletions .github/guides/TESTGUIDE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Guide for writing a test

Before starting to write a test on your own, it might be instructive to follow common test practices in `/test/verifiedTests`. A style guide on how to write tests is given [here](STYLEGUIDE.md).
Before starting to write a test on your own, it might be instructive to follow common test practices in `/test/verifiedTests`. A style guide on how to write tests is given [here](https://github.com/opencobra/cobratoolbox/blob/master/.github/guides/STYLEGUIDE.md).

## Test if an output is correct

Expand Down Expand Up @@ -34,7 +34,7 @@ The test succeeds if the argument of `assert()` yields a `true` logical conditio

## Test if a function throws an error or warning message

If you want to test whether your `function1` correctly throws an error/warning message, you can test as follows:
If you want to test whether your `function1` correctly throws an **error** message, you can test as follows:
````Matlab
% Case 5: test with 2 input and 1 output arguments (2nd input argument is of wrong dimension)
try
Expand All @@ -43,11 +43,19 @@ catch ME
assert(length(ME.message) > 0)
end
````

If you want to test whether your `function1` correctly throws a **warning** message, you can test as follows:
````Matlab
warning('off', 'all')
output1 = function1(input1, input2');
assert(length(lastwarn()) > 0)
warning('on', 'all')
````
Note that this allows the error message to be thrown without failing the test.

## Test template

A test template is readily available [here](testTemplate.m). The following sections shall be included in a test file:
A test template is readily available [here](https://github.com/opencobra/cobratoolbox/blob/master/.github/guides/testTemplate.m). The following sections shall be included in a test file:

#### 1. Header
````Matlab
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p align="center">
<img src="https://raw.githubusercontent.com/laurentheirendt/cobratoolbox/simplified-doc/docs/source/_static/logo.png" height="160px"/>
<img src="https://raw.githubusercontent.com/opencobra/cobratoolbox/master/docs/source/_static/logo.png" height="160px"/>
</p>

The COBRA Toolbox <br> COnstraint-Based Reconstruction and Analysis Toolbox
Expand Down
18 changes: 13 additions & 5 deletions initCobraToolbox.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ function initCobraToolbox()
global CBTDIR;
global SOLVERS;
global OPT_PROB_TYPES;
global CBT_LP_SOLVER;
global CBT_MILP_SOLVER;
global CBT_QP_SOLVER;
global CBT_MIQP_SOLVER;
global CBT_NLP_SOLVER;
global GUROBI_PATH;
global ILOG_CPLEX_PATH;
global TOMLAB_PATH;
Expand Down Expand Up @@ -328,11 +333,15 @@ function initCobraToolbox()
end
end

% set the default solver
% set the default solver and print out the default variables
if ENV_VARS.printLevel
fprintf(' > Setting default LP solver to GLPK ... ');
fprintf(' > Setting default solvers ...\n');
changeCobraSolver('glpk', 'LP');
fprintf('Done.\n');
for k = 1:length(OPT_PROB_TYPES)
varName = horzcat(['CBT_', OPT_PROB_TYPES{k}, '_SOLVER']);
fprintf([' - ', varName, ' = \''', eval(varName), '\'';\n'])
end
fprintf(' Done.\n');
end

% print out a summary table
Expand Down Expand Up @@ -400,9 +409,8 @@ function initCobraToolbox()
end
end
end

if ENV_VARS.printLevel
fprintf('\n')
fprintf('\n');
end

% change back to the current directory
Expand Down
10 changes: 7 additions & 3 deletions src/solvers/changeCobraSolver.m
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
end

% legacy support for other versions of gurobi
if strcmp(solverName, 'gurobi') || strcmp(solverName, 'gurobi6') || strcmp(solverName, 'gurobi7')
if strcmpi(solverName, 'gurobi') || strcmpi(solverName, 'gurobi6') || strcmpi(solverName, 'gurobi7')
solverName = 'gurobi';
end

Expand All @@ -182,7 +182,7 @@
end

% Attempt to set the user provided solver for all optimization problem types
if (strcmp(solverType, 'ALL'))
if strcmpi(solverType, 'all')
for i = 1:length(OPT_PROB_TYPES)
changeCobraSolver(solverName, OPT_PROB_TYPES{i}, 0);
end
Expand Down Expand Up @@ -267,7 +267,8 @@
case 'gurobi_mex'
solverOK = checkSolverInstallationFile(solverName, 'gurobi_mex', printLevel);
case 'gurobi'
if isunix, tmpGurobi = 'gurobi.sh', else, 'gurobi.bat', end;
tmpGurobi = 'gurobi.sh';
if ispc, tmpGurobi = 'gurobi.bat'; end
solverOK = checkGurobiInstallation(solverName, tmpGurobi, printLevel);
case 'mps'
solverOK = checkSolverInstallationFile(solverName, 'BuildMPS', printLevel);
Expand Down Expand Up @@ -295,6 +296,9 @@
if solverOK
varName = horzcat(['CBT_', solverType, '_SOLVER']);
eval([varName ' = solverName;']);
if strcmpi(solverType, 'all')
fprintf([' > ', varName, ' has been set to ', solverName, '.\n']);
end
end

end
Expand Down
4 changes: 2 additions & 2 deletions src/solvers/solveCobraMILP.m
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@
solStat = 3; % Other problem, but integer solution exists
end

case 'gurobi'
case 'gurobi_mex'
% Free academic licenses for the Gurobi solver can be obtained from
% http://www.gurobi.com/html/academic.html
%
Expand Down Expand Up @@ -419,7 +419,7 @@
delete('clone1.log')
end

case {'gurobi5','gurobi6'}
case 'gurobi'
%% gurobi 5
% Free academic licenses for the Gurobi solver can be obtained from
% http://www.gurobi.com/html/academic.html
Expand Down
52 changes: 26 additions & 26 deletions src/solvers/solveCobraMIQP.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
%
% solution = solveCobraQP(MIQPproblem,solver,verbFlag,solverParams)
%
% % Solves problems of the type
% % Solves problems of the type
%
% min osense * 0.5 x' * F * x + osense * c' * x
% s/t lb <= x <= ub
Expand All @@ -20,8 +20,8 @@
% lb Lower bound vector
% ub Upper bound vector
% osense Objective sense (-1 max, +1 min)
% csense Constraint senses, a string containting the constraint
% sense for each row in A ('E', equality, 'G' greater
% csense Constraint senses, a string containting the constraint
% sense for each row in A ('E', equality, 'G' greater
% than, 'L' less than).
%
%OPTIONAL INPUTS
Expand All @@ -30,7 +30,7 @@
%
% parameters Structure containing optional parameters as fields.
% printLevel Print level for solver
% saveInput Saves LPproblem to filename specified in field.
% saveInput Saves LPproblem to filename specified in field.
% Setting parameters = 'default' uses default setting set in
% getCobraSolverParameters.
%
Expand All @@ -49,7 +49,7 @@
% 0 Infeasible QP
% -1 No optimal solution found (time limit etc)
% 3 Solution exists but with problems
% origStat Original status returned by the specific solver
% origStat Original status returned by the specific solver
% time Solve time in seconds
%
%
Expand Down Expand Up @@ -107,10 +107,10 @@
tomlabProblem = miqpAssign(osense*F, osense*c, A, b_L, b_U, lb, ub,[], ...
intVars, [],[],[],'CobraMIQP');
tomlabProblem.CPLEX.LogFile = 'MIQPproblem.log';

%optional parameters
PriLvl = printLevel;

%Save Input if selected
if ~isempty(saveInput)
fileName = parameters.saveInput;
Expand All @@ -123,7 +123,7 @@
tomlabProblem.MIP.cpxControl.TILIM = timeLimit; % time limit
tomlabProblem.MIP.cpxControl.THREADS = 1; % by default use only one thread
Result = tomRun('cplex', tomlabProblem, PriLvl);

x = Result.x_k;
f = osense*Result.f_k;
stat = Result.Inform;
Expand All @@ -143,7 +143,7 @@
solStat = 3; % Solution exists, but either scaling problems or not proven to be optimal
end
%%
case 'gurobi'
case 'gurobi_mex'
% Free academic licenses for the Gurobi solver can be obtained from
% http://www.gurobi.com/html/academic.html
%
Expand All @@ -153,15 +153,15 @@
clear opts % Use the default parameter settings
if printLevel == 0
% Version v1.10 of Gurobi Mex has a minor bug. For complete silence
% Remove Line 736 of gurobi_mex.c: mexPrintf("\n");
% Remove Line 736 of gurobi_mex.c: mexPrintf("\n");
opts.Display = 0;
opts.DisplayInterval = 0;
else
opts.Display = 1;
end



if (isempty(csense))
clear csense
csense(1:length(b),1) = '=';
Expand All @@ -171,26 +171,26 @@
csense(csense == 'E') = '=';
csense = csense(:);
end
% Gurobi passes individual terms instead of an F matrix. qrow and

% Gurobi passes individual terms instead of an F matrix. qrow and
% qcol specify which variables are multipled to get each term,
% while qval specifies the coefficients of each term.

[qrow,qcol,qval]=find(F);
qrow=qrow'-1; % -1 because gurobi numbers indices from zero, not one.
qcol=qcol'-1;
qval=0.5*qval';
opts.QP.qrow = int32(qrow);
opts.QP.qcol = int32(qcol);

opts.QP.qrow = int32(qrow);
opts.QP.qcol = int32(qcol);
opts.QP.qval = qval;
opts.Method = 0; % 0 - primal, 1 - dual
opts.Presolve = -1; % -1 - auto, 0 - no, 1 - conserv, 2 - aggressive
opts.FeasibilityTol = 1e-6;
opts.IntFeasTol = 1e-5;
opts.OptimalityTol = 1e-6;
%opt.Quad=1;

%gurobi_mex doesn't cast logicals to doubles automatically
c = double(c);
[x,f,origStat,output,y] = gurobi_mex(c,osense,sparse(A),b, ...
Expand All @@ -207,13 +207,13 @@
stat = -1; % Solution not optimal or solver problem
end
solStat = stat;
case 'gurobi5'
case 'gurobi'
%% gurobi5
% Free academic licenses for the Gurobi solver can be obtained from
% http://www.gurobi.com/html/academic.html
resultgurobi = struct('x',[],'objval',[],'pi',[]);
clear params % Use the default parameter settings
if printLevel == 0
if printLevel == 0
params.OutputFlag = 0;
params.DisplayInterval = 1;
else
Expand All @@ -226,7 +226,7 @@
params.IntFeasTol = 1e-5;
params.FeasibilityTol = 1e-6;
params.OptimalityTol = 1e-6;

if (isempty(MIQPproblem.csense))
clear MIQPproblem.csense
MIQPproblem.csense(1:length(b),1) = '=';
Expand All @@ -236,13 +236,13 @@
MIQPproblem.csense(MIQPproblem.csense == 'E') = '=';
MIQPproblem.csense = MIQPproblem.csense(:);
end

if MIQPproblem.osense == -1
MIQPproblem.osense = 'max';
else
MIQPproblem.osense = 'min';
end

MIQPproblem.vtype = vartype;
MIQPproblem.Q = 0.5*sparse(MIQPproblem.F);
MIQPproblem.modelsense = MIQPproblem.osense;
Expand All @@ -251,7 +251,7 @@
solStat = resultgurobi.status;
if strcmp(resultgurobi.status,'OPTIMAL')
stat = 1; % Optimal solution found

if exist('resultgurobi.pi')
[x,f,y] = deal(resultgurobi.x,resultgurobi.objval,resultgurobi.pi);
else
Expand All @@ -276,6 +276,6 @@
solution.obj = f;
solution.solver = solver;
solution.stat = solStat;
solution.origStat = stat;
solution.origStat = stat;
solution.time = t;
solution.full = x;
solution.full = x;
Loading

0 comments on commit 24b38d6

Please sign in to comment.