summaryrefslogtreecommitdiff
path: root/macros/intqpipopt.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/intqpipopt.sci')
-rw-r--r--macros/intqpipopt.sci461
1 files changed, 461 insertions, 0 deletions
diff --git a/macros/intqpipopt.sci b/macros/intqpipopt.sci
new file mode 100644
index 0000000..f45d9cb
--- /dev/null
+++ b/macros/intqpipopt.sci
@@ -0,0 +1,461 @@
+// Copyright (C) 2016 - IIT Bombay - FOSSEE
+//
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution. The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+// Author: Pranav Deshpande and Akshay Miterani
+// Organization: FOSSEE, IIT Bombay
+// Email: toolbox@scilab.in
+
+function varargout = intqpipopt (varargin)
+ // Solves a linear quadratic problem.
+ //
+ // Calling Sequence
+ // xopt = intqpipopt(H,f)
+ // xopt = intqpipopt(H,f,intcon)
+ // xopt = intqpipopt(H,f,intcon,A,b)
+ // xopt = intqpipopt(H,f,intcon,A,b,Aeq,beq)
+ // xopt = intqpipopt(H,f,intcon,A,b,Aeq,beq,lb,ub)
+ // xopt = intqpipopt(H,f,intcon,A,b,Aeq,beq,lb,ub,x0)
+ // xopt = intqpipopt(H,f,intcon,A,b,Aeq,beq,lb,ub,x0,options)
+ // xopt = intqpipopt(H,f,intcon,A,b,Aeq,beq,lb,ub,x0,options,"file_path")
+ // [xopt,fopt,exitflag,output] = intqpipopt( ... )
+ //
+ // Parameters
+ // H : a symmetric matrix of double, represents coefficients of quadratic in the quadratic problem.
+ // f : a vector of double, represents coefficients of linear in the quadratic problem
+ // intcon : a vector of integers, represents which variables are constrained to be integers
+ // A : a matrix of double, represents the linear coefficients in the inequality constraints A⋅x ≤ b.
+ // b : a vector of double, represents the linear coefficients in the inequality constraints A⋅x ≤ b.
+ // Aeq : a matrix of double, represents the linear coefficients in the equality constraints Aeq⋅x = beq.
+ // beq : a vector of double, represents the linear coefficients in the equality constraints Aeq⋅x = beq.
+ // lb : a vector of double, contains lower bounds of the variables.
+ // ub : a vector of double, contains upper bounds of the variables.
+ // x0 : a vector of double, contains initial guess of variables.
+ // options : a list containing the parameters to be set.
+ // file_path : path to bonmin opt file if used.
+ // xopt : a vector of double, the computed solution of the optimization problem.
+ // fopt : a double, the value of the function at x.
+ // exitflag : The exit status. See below for details.
+ // output : The structure consist of statistics about the optimization. See below for details.
+ //
+ // Description
+ // Search the minimum of a constrained linear quadratic optimization problem specified by :
+ //
+ // <latex>
+ // \begin{eqnarray}
+ // &\mbox{min}_{x}
+ // & 1/2⋅x^T⋅H⋅x + f^T⋅x \\
+ // & \text{subject to} & A⋅x \leq b \\
+ // & & Aeq⋅x = beq \\
+ // & & lb \leq x \leq ub \\
+ // & & x_i \in \!\, \mathbb{Z}, i \in \!\, intcon\\
+ // \end{eqnarray}
+ // </latex>
+ //
+ // The routine calls Bonmin for solving the quadratic problem, Bonmin is a library written in C++.
+ //
+ // The exitflag allows to know the status of the optimization which is given back by Bonmin.
+ // <itemizedlist>
+ // <listitem>exitflag=0 : Optimal Solution Found. </listitem>
+ // <listitem>exitflag=1 : InFeasible Solution.</listitem>
+ // <listitem>exitflag=2 : Output is Continuous Unbounded.</listitem>
+ // <listitem>exitflag=3 : Limit Exceeded.</listitem>
+ // <listitem>exitflag=4 : User Interrupt.</listitem>
+ // <listitem>exitflag=5 : MINLP Error.</listitem>
+ // </itemizedlist>
+ //
+ // For more details on exitflag see the Bonmin page, go to http://www.coin-or.org/Bonmin
+ //
+ // The output data structure contains detailed informations about the optimization process.
+ // It has type "struct" and contains the following fields.
+ // <itemizedlist>
+ // <listitem>output.constrviolation: The max-norm of the constraint violation.</listitem>
+ // </itemizedlist>
+ //
+ // Examples
+ // H = [1 -1; -1 2];
+ // f = [-2; -6];
+ // A = [1 1; -1 2; 2 1];
+ // b = [2; 2; 3];
+ // lb=[0,0];
+ // ub=[%inf, %inf];
+ // intcon = [1 2];
+ //[xopt,fopt,status,output]=intqpipopt(H,f,intcon,A,b,[],[],lb,ub)
+ //
+ // Examples
+ // //Find x in R^6 such that:
+ // Aeq= [1,-1,1,0,3,1;
+ // -1,0,-3,-4,5,6;
+ // 2,5,3,0,1,0];
+ // beq=[1; 2; 3];
+ // A= [0,1,0,1,2,-1;
+ // -1,0,2,1,1,0];
+ // b = [-1; 2.5];
+ // lb=[-1000; -10000; 0; -1000; -1000; -1000];
+ // ub=[10000; 100; 1.5; 100; 100; 1000];
+ // x0 = repmat(0,6,1);
+ // param = list("MaxIter", 300, "CpuTime", 100);
+ // //and minimize 0.5*x'*H*x + f'*x with
+ // f=[1; 2; 3; 4; 5; 6]; H=eye(6,6);
+ // intcon = [2 4];
+ // [xopt,fopt,exitflag,output]=intqpipopt(H,f,intcon,A,b,Aeq,beq,lb,ub,x0,param)
+ // Authors
+ // Akshay Miterani and Pranav Deshpande
+
+ //To check the number of input and output argument
+ [lhs , rhs] = argn();
+
+ //To check the number of argument given by user
+ if ( rhs < 2 | rhs == 4 | rhs == 6 | rhs == 8 | rhs > 12 ) then
+ errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while should be in the set of [2 3 5 7 9 10 11 12]"), "intqpipopt", rhs);
+ error(errmsg)
+ end
+
+ //To check the number of output arguments
+ if lhs > 4 then
+ errmsg = msprintf(gettext("%s: Unexpected number of output arguments: %d provided while should be in the set of [1 2 3 4]"), "intqpipopt", lhs);
+ end
+
+ H = [];
+ f = [];
+ intcon = [];
+ A = [];
+ b = [];
+ Aeq = [];
+ beq = [];
+ lb = [];
+ ub = [];
+ options = list();
+ bonmin_options_file = '';
+
+ H = varargin(1);
+ f = varargin(2);
+ nbVar = size(H,1);
+
+ if(nbVar == 0) then
+ errmsg = msprintf(gettext("%s: Cannot determine the number of variables because input objective coefficients is empty"), "intqpipopt");
+ error(errmsg);
+ end
+
+ if ( rhs>=3 ) then
+ intcon=varargin(3);
+ end
+
+ if ( rhs<=3 ) then
+ A = []
+ b = []
+ else
+ A = varargin(4);
+ b = varargin(5);
+ end
+
+ if ( rhs<6 ) then
+ Aeq = []
+ beq = []
+ else
+ Aeq = varargin(6);
+ beq = varargin(7);
+ end
+
+ if ( rhs<8 ) then
+ lb = repmat(-%inf,nbVar,1);
+ ub = repmat(%inf,nbVar,1);
+ else
+ lb = varargin(8);
+ ub = varargin(9);
+ end
+
+
+ if ( rhs<10 | size(varargin(10)) ==0 ) then
+ x0 = repmat(0,nbVar,1)
+ else
+ x0 = varargin(10);
+ end
+
+ if (rhs<11|size(varargin(11))==0) then
+ options = list();
+ else
+ options = varargin(11);
+ end
+
+ if(rhs==12) then
+ bonmin_options_file=varargin(12);
+ end
+
+ if (size(lb,2)==0) then
+ lb = repmat(-%inf,nbVar,1);
+ end
+
+ if (size(ub,2)==0) then
+ ub = repmat(%inf,nbVar,1);
+ end
+
+ if (size(f,2)==0) then
+ f = repmat(0,nbVar,1);
+ end
+
+ //Check type of variables
+ Checktype("intqpipopt", H, "H", 1, "constant")
+ Checktype("intqpipopt", f, "f", 2, "constant")
+ Checktype("intqpipopt", intcon, "intcon", 3, "constant")
+ Checktype("intqpipopt", A, "A", 4, "constant")
+ Checktype("intqpipopt", b, "b", 5, "constant")
+ Checktype("intqpipopt", Aeq, "Aeq", 6, "constant")
+ Checktype("intqpipopt", beq, "beq", 7, "constant")
+ Checktype("intqpipopt", lb, "lb", 8, "constant")
+ Checktype("intqpipopt", ub, "ub", 9, "constant")
+ Checktype("intqpipopt", x0, "x0", 10, "constant")
+ Checktype("intqpipopt", options, "options", 11, "list")
+ Checktype("intqpipopt", bonmin_options_file, "bonmin_options_file", 12, "string")
+
+ nbConInEq = size(A,1);
+ nbConEq = size(Aeq,1);
+
+ // Check if the user gives row vector
+ // and Changing it to a column matrix
+
+ if (size(f,2)== [nbVar]) then
+ f=f';
+ end
+
+ if (size(lb,2)== [nbVar]) then
+ lb = lb';
+ end
+
+ if (size(ub,2)== [nbVar]) then
+ ub = ub';
+ end
+
+ if (size(b,2)==nbConInEq) then
+ b = b';
+ end
+
+ if (size(beq,2)== nbConEq) then
+ beq = beq';
+ end
+
+ if (size(x0,2)== [nbVar]) then
+ x0=x0';
+ end
+
+ //Checking the H matrix which needs to be a symmetric matrix
+ if ( ~isequal(H,H')) then
+ errmsg = msprintf(gettext("%s: H is not a symmetric matrix"), "intqpipopt");
+ error(errmsg);
+ end
+
+ //Check the size of f which should equal to the number of variable
+ if ( size(f,1) ~= [nbVar]) then
+ errmsg = msprintf(gettext("%s: The number of rows and columns in H must be equal the number of elements of f"), "intqpipopt");
+ error(errmsg);
+ end
+
+ //Error Checks for intcon
+
+ for i=1:size(intcon,2)
+ if(intcon(i)>nbVar) then
+ errmsg = msprintf(gettext("%s: The values inside intcon should be less than the number of variables"), "intqpipopt");
+ error(errmsg);
+ end
+
+ if (intcon(i)<0) then
+ errmsg = msprintf(gettext("%s: The values inside intcon should be greater than 0 "), "intqpipopt");
+ error(errmsg);
+ end
+
+ if(modulo(intcon(i),1)) then
+ errmsg = msprintf(gettext("%s: The values inside intcon should be an integer "), "intqpipopt");
+ error(errmsg);
+ end
+ end
+
+ //Check the size of inequality constraint which should be equal to the number of variables
+ if ( size(A,2) ~= nbVar & size(A,2) ~= 0) then
+ errmsg = msprintf(gettext("%s: The number of columns in A must be the same as the number of elements of f"), "intqpipopt");
+ error(errmsg);
+ end
+
+ //Check the size of equality constraint which should be equal to the number of variables
+ if ( size(Aeq,2) ~= nbVar & size(Aeq,2) ~= 0 ) then
+ errmsg = msprintf(gettext("%s: The number of columns in Aeq must be the same as the number of elements of f"), "intqpipopt");
+ error(errmsg);
+ end
+
+ //Check the size of Lower Bound which should be equal to the number of variables
+ if ( size(lb,1) ~= nbVar) then
+ errmsg = msprintf(gettext("%s: The Lower Bound is not equal to the number of variables"), "intqpipopt");
+ error(errmsg);
+ end
+
+ //Check the size of Upper Bound which should equal to the number of variables
+ if ( size(ub,1) ~= nbVar) then
+ errmsg = msprintf(gettext("%s: The Upper Bound is not equal to the number of variables"), "intqpipopt");
+ error(errmsg);
+ end
+
+ //Check the size of constraints of Lower Bound which should equal to the number of constraints
+ if ( size(b,1) ~= nbConInEq & size(b,1) ~= 0) then
+ errmsg = msprintf(gettext("%s: The number of rows in A must be the same as the number of elements of b"), "intqpipopt");
+ error(errmsg);
+ end
+
+ //Check the size of constraints of Upper Bound which should equal to the number of constraints
+ if ( size(beq,1) ~= nbConEq & size(beq,1) ~= 0) then
+ errmsg = msprintf(gettext("%s: The number of rows in Aeq must be the same as the number of elements of beq"), "intqpipopt");
+ error(errmsg);
+ end
+
+ //Check the size of initial of variables which should equal to the number of variables
+ if ( size(x0,1) ~= nbVar) then
+ warnmsg = msprintf(gettext("%s: Ignoring initial guess of variables as it is not equal to the number of variables"), "intqpipopt");
+ warning(warnmsg);
+ x0 = repmat(0,nbVar,1);
+ end
+
+ //Check if the user gives a matrix instead of a vector
+
+ if ((size(f,1)~=1)& (size(f,2)~=1)) then
+ errmsg = msprintf(gettext("%s: f should be a vector"), "intqpipopt");
+ error(errmsg);
+ end
+
+ if (size(lb,1)~=1)& (size(ub,2)~=1) then
+ errmsg = msprintf(gettext("%s: Lower Bound should be a vector"), "intqpipopt");
+ error(errmsg);
+ end
+
+ if (size(ub,1)~=1)& (size(ub,2)~=1) then
+ errmsg = msprintf(gettext("%s: Upper Bound should be a vector"), "intqpipopt");
+ error(errmsg);
+ end
+
+ if (nbConInEq) then
+ if ((size(b,1)~=1)& (size(b,2)~=1)) then
+ errmsg = msprintf(gettext("%s: Constraint Lower Bound should be a vector"), "intqpipopt");
+ error(errmsg);
+ end
+ end
+
+ if (nbConEq) then
+ if (size(beq,1)~=1)& (size(beq,2)~=1) then
+ errmsg = msprintf(gettext("%s: Constraint should be a vector"), "intqpipopt");
+ error(errmsg);
+ end
+ end
+
+ for i = 1:nbConInEq
+ if (b(i) == -%inf) then
+ errmsg = msprintf(gettext("%s: Value of b can not be negative infinity"), "intqpipopt");
+ error(errmsg);
+ end
+ end
+
+ for i = 1:nbConEq
+ if (beq(i) == -%inf) then
+ errmsg = msprintf(gettext("%s: Value of beq can not be negative infinity"), "intqpipopt");
+ error(errmsg);
+ end
+ end
+
+ for i = 1:nbVar
+ if(lb(i)>ub(i)) then
+ errmsg = msprintf(gettext("%s: Problem has inconsistent variable bounds"), "intqpipopt");
+ error(errmsg);
+ end
+ end
+
+ // Checking if the specified options file exists or not
+ if (~isfile(bonmin_options_file) & ~bonmin_options_file=='') then
+ error(999, 'The specified options file does not exist!');
+ end
+
+ // Validating Options
+ if (type(options) ~= 15) then
+ errmsg = msprintf(gettext("%s: Options should be a list "), "cbcintlinprog");
+ error(errmsg);
+ end
+
+
+ if (modulo(size(options),2)) then
+ errmsg = msprintf(gettext("%s: Size of parameters should be even"), "cbcintlinprog");
+ error(errmsg);
+ end
+
+ //Pusing options as required to a double array
+ optval = [];
+ ifval =[];
+ if length(options) == 0 then
+ optval = [0 0 0 0 0];
+ ifval = [0 0 0 0 0];
+ else
+ optval = [0 0 0 0 0];
+ ifval = [0 0 0 0 0];
+ for i=1:2:length(options)
+ select convstr(options(i),'l')
+ case 'integertolerance' then
+ ifval(1) = 1;
+ optval(1) = options(i+1);
+ case 'maxnodes' then
+ ifval(2) = 1;
+ optval(2) = options(i+1);
+ case 'cputime' then
+ ifval(3) = 1;
+ optval(3) = options(i+1);
+ case 'allowablegap' then
+ ifval(4) = 1;
+ optval(4) = options(i+1);
+ case 'maxiter' then
+ ifval(5) = 1;
+ optval(5) = options(i+1);
+ else
+ error(999, 'Unknown string argument passed.');
+ end
+ end
+ end
+
+ //Converting it into bonmin format
+ f = f';
+ lb = lb';
+ ub = ub';
+ x0 = x0';
+ conMatrix = [Aeq;A];
+ nbCon = size(conMatrix,1);
+ conLB = [beq; repmat(-%inf,nbConInEq,1)]';
+ conUB = [beq;b]';
+ intcon = intcon'
+ intconSize = length(intcon);
+ xopt=[]
+ fopt=[]
+ status=[]
+ [xopt,fopt,status] = sci_intqpipopt(nbVar,nbCon,intconSize,H,f,intcon,conMatrix,conLB,conUB,lb,ub,x0,optval,ifval,bonmin_options_file);
+ xopt = xopt';
+
+ output.ConstrViolation = max([0;norm(Aeq*xopt-beq, 'inf');(lb'-xopt);(xopt-ub');(A*xopt-b)]);
+
+ varargout(1) = xopt
+ varargout(2) = fopt
+ varargout(3) = status
+ varargout(4) = output
+
+ select status
+ case 0 then
+ printf("\nOptimal Solution Found.\n");
+ case 1 then
+ printf("\nInFeasible Solution.\n");
+ case 2 then
+ printf("\nOutput is Continuous Unbounded.s\n");
+ case 3 then
+ printf("\nLimit Exceeded.\n");
+ case 4 then
+ printf("\nUser Interrupt.\n");
+ case 5 then
+ printf("\nMINLP Error.\n");
+ else
+ printf("\nInvalid status returned. Notify the Toolbox authors\n");
+ break;
+ end
+
+endfunction