function solver = definesolvers
% ****************************
% Create a default solver
% ****************************
emptysolver.tag = '';
emptysolver.version = ''; % Developer/from module
emptysolver.subversion = ''; % Typically the release number
emptysolver.checkfor = {''};
emptysolver.versionnumbercreator = []; % A function returning e.g. x.y.z
emptysolver.requiredversionnumber= [];
emptysolver.detector= [];
emptysolver.call = '';
emptysolver.subcall = '';
emptysolver.show = 1;
emptysolver.usesother = 0;
emptysolver.builtin = 0;
emptysolver.supportsinitial = 0;
emptysolver.supportsinitialNAN = 0;
emptysolver.supportshighprec = 0;
emptysolver.objective.linear = 0;
emptysolver.objective.quadratic.convex = 0;
emptysolver.objective.quadratic.nonconvex = 0;
emptysolver.objective.quadratic.nonnegative = 0;
emptysolver.objective.polynomial = 0;
emptysolver.objective.maxdet.convex = 0;
emptysolver.objective.maxdet.nonconvex = 0;
emptysolver.objective.sigmonial = 0;
emptysolver.constraint.equalities.linear = 0;
emptysolver.constraint.equalities.quadratic = 0;
emptysolver.constraint.equalities.polynomial = 0;
emptysolver.constraint.equalities.sigmonial = 0;
emptysolver.constraint.equalities.multiterm = 1;
emptysolver.constraint.inequalities.elementwise.linear = 0;
emptysolver.constraint.inequalities.elementwise.quadratic.convex = 0;
emptysolver.constraint.inequalities.elementwise.quadratic.nonconvex = 0;
emptysolver.constraint.inequalities.elementwise.quadratic.nonegative = 0;
emptysolver.constraint.inequalities.elementwise.polynomial = 0;
emptysolver.constraint.inequalities.elementwise.sigmonial = 0;
emptysolver.constraint.inequalities.semidefinite.linear = 0;
emptysolver.constraint.inequalities.semidefinite.quadratic = 0;
emptysolver.constraint.inequalities.semidefinite.polynomial = 0;
emptysolver.constraint.inequalities.semidefinite.sigmonial = 0;
emptysolver.constraint.inequalities.rank = 0;
emptysolver.constraint.inequalities.secondordercone.linear = 0;
emptysolver.constraint.inequalities.secondordercone.nonlinear = 0;
emptysolver.constraint.inequalities.rotatedsecondordercone.linear = 0;
emptysolver.constraint.inequalities.rotatedsecondordercone.nonlinear = 0;
emptysolver.constraint.complementarity.variable = 0;
emptysolver.constraint.complementarity.linear = 0;
emptysolver.constraint.complementarity.nonlinear = 0;
emptysolver.constraint.integer = 0;
emptysolver.constraint.binary = 0;
emptysolver.constraint.semivar = 0;
emptysolver.constraint.semiintvar = 0;
emptysolver.constraint.sos1 = 0;
emptysolver.constraint.sos2 = 0;
emptysolver.dual = 0;
emptysolver.complex = 0;
emptysolver.interval = 0;
emptysolver.parametric = 0;
emptysolver.evaluation = 0;
emptysolver.exponentialcone = 0;
emptysolver.powercone = 0;
emptysolver.uncertain = 0;
emptysolver.global = 0;
% **************************************
% Some standard solvers to simplify code
% **************************************
% LP solver
lpsolver = emptysolver;
lpsolver.objective.linear = 1;
lpsolver.constraint.equalities.linear = 1;
lpsolver.constraint.inequalities.elementwise.linear = 1;
lpsolver.dual = 1;
lpsolver.global = 1;
% QP solver
qpsolver = emptysolver;
qpsolver.objective.linear = 1;
qpsolver.objective.quadratic.convex = 1;
qpsolver.constraint.equalities.linear = 1;
qpsolver.constraint.inequalities.elementwise.linear = 1;
qpsolver.dual = 1;
qpsolver.global = 1;
% SDP solver
sdpsolver = emptysolver;
sdpsolver.objective.linear = 1;
sdpsolver.constraint.equalities.linear = 1;
sdpsolver.constraint.inequalities.elementwise.linear = 1;
sdpsolver.constraint.inequalities.semidefinite.linear = 1;
sdpsolver.dual = 1;
sdpsolver.global = 1;
% ****************************
% INITIALIZE COUNTER
% ****************************
i = 1;
% ****************************
% DEFINE SOLVERS
% ****************************
solver(i) = qpsolver;
solver(i).tag = 'GUROBI';
solver(i).version = '';
solver(i).checkfor= {'gurobi'};
solver(i).call = 'callgurobi';
solver(i).constraint.inequalities.elementwise.quadratic.convex = 1;
solver(i).constraint.inequalities.secondordercone.linear = 1;
solver(i).constraint.integer = 1;
solver(i).constraint.binary = 1;
solver(i).constraint.semivar = 1;
solver(i).constraint.sos2 = 1;
solver(i).supportsinitial = 1;
solver(i).supportsinitialNAN = 1;
i = i+1;
solver(i) = qpsolver;
solver(i).tag = 'GUROBI';
solver(i).version = 'NONCONVEX';
solver(i).checkfor= {'gurobi'};
solver(i).call = 'callgurobi';
solver(i).objective.quadratic.nonconvex = 1;
solver(i).constraint.inequalities.elementwise.quadratic.convex = 1;
solver(i).constraint.inequalities.elementwise.quadratic.nonconvex = 1;
solver(i).constraint.equalities.quadratic = 1;
solver(i).constraint.inequalities.secondordercone.linear = 1;
solver(i).constraint.integer = 1;
solver(i).constraint.binary = 1;
solver(i).constraint.semivar = 1;
solver(i).constraint.sos2 = 1;
solver(i).supportsinitial = 1;
solver(i).supportsinitialNAN = 1;
i = i+1;
solver(i) = qpsolver;
solver(i).tag = 'CPLEX';
solver(i).version = 'IBM';
solver(i).subversion = '12.10.0';
solver(i).checkfor= {'cplexqcp.m','cplexlink12100'};
solver(i).call = 'call_cplexibm_qcmiqp';
solver(i).objective.quadratic.convex = 1;
solver(i).constraint.inequalities.elementwise.quadratic.convex = 1;
solver(i).constraint.inequalities.secondordercone.linear = 1;
solver(i).constraint.integer = 1;
solver(i).constraint.binary = 1;
solver(i).constraint.sos2 = 1;
solver(i).constraint.semivar = 1;
solver(i).constraint.semiintvar = 1;
solver(i).supportsinitial = 1;
i = i+1;
solver(i) = qpsolver;
solver(i).tag = 'CPLEX';
solver(i).version = 'IBM';
solver(i).subversion = '12.10.0';
solver(i).checkfor= {'cplexqcp.m','cplexlink12100'};
solver(i).call = 'call_cplexibm_qcmiqp';
solver(i).objective.quadratic.nonconvex = 1;
solver(i).constraint.integer = 1;
solver(i).constraint.binary = 1;
solver(i).constraint.sos2 = 1;
solver(i).constraint.semivar = 1;
solver(i).constraint.semiintvar = 1;
solver(i).supportsinitial = 1;
i = i+1;
solver(i) = qpsolver;
solver(i).tag = 'CPLEX';
solver(i).version = 'IBM';
solver(i).subversion = '12.9.0';
solver(i).checkfor= {'cplexqcp.m','cplexlink1290'};
solver(i).call = 'call_cplexibm_qcmiqp';
solver(i).objective.quadratic.convex = 1;
solver(i).constraint.inequalities.elementwise.quadratic.convex = 1;
solver(i).constraint.inequalities.secondordercone.linear = 1;
solver(i).constraint.integer = 1;
solver(i).constraint.binary = 1;
solver(i).constraint.sos2 = 1;
solver(i).constraint.semivar = 1;
solver(i).constraint.semiintvar = 1;
solver(i).supportsinitial = 1;
i = i+1;
solver(i) = qpsolver;
solver(i).tag = 'CPLEX';
solver(i).version = 'IBM';
solver(i).subversion = '12.9.0';
solver(i).checkfor= {'cplexqcp.m','cplexlink1290'};
solver(i).call = 'call_cplexibm_qcmiqp';
solver(i).objective.quadratic.nonconvex = 1;
solver(i).constraint.integer = 1;
solver(i).constraint.binary = 1;
solver(i).constraint.sos2 = 1;
solver(i).constraint.semivar = 1;
solver(i).constraint.semiintvar = 1;
solver(i).supportsinitial = 1;
i = i+1;
solver(i) = qpsolver;
solver(i).tag = 'CPLEX';
solver(i).version = 'IBM';
solver(i).subversion = '12.8.0';
solver(i).checkfor= {'cplexqcp.m','cplexlink1280'};
solver(i).call = 'call_cplexibm_qcmiqp';
solver(i).objective.quadratic.convex = 1;
solver(i).constraint.inequalities.elementwise.quadratic.convex = 1;
solver(i).constraint.inequalities.secondordercone.linear = 1;
solver(i).constraint.integer = 1;
solver(i).constraint.binary = 1;
solver(i).constraint.sos2 = 1;
solver(i).constraint.semivar = 1;
solver(i).constraint.semiintvar = 1;
solver(i).supportsinitial = 1;
i = i+1;
solver(i) = qpsolver;
solver(i).tag = 'CPLEX';
solver(i).version = 'IBM';
solver(i).subversion = '12.8.0';
solver(i).checkfor= {'cplexqcp.m','cplexlink1280'};
solver(i).call = 'call_cplexibm_qcmiqp';
solver(i).objective.quadratic.nonconvex = 1;
solver(i).constraint.integer = 1;
solver