summaryrefslogtreecommitdiff
path: root/macros/matrix_linprog.sci
diff options
context:
space:
mode:
Diffstat (limited to 'macros/matrix_linprog.sci')
-rwxr-xr-xmacros/matrix_linprog.sci245
1 files changed, 245 insertions, 0 deletions
diff --git a/macros/matrix_linprog.sci b/macros/matrix_linprog.sci
new file mode 100755
index 0000000..1f6a6bf
--- /dev/null
+++ b/macros/matrix_linprog.sci
@@ -0,0 +1,245 @@
+// Copyright (C) 2015 - IIT Bombay - FOSSEE
+//
+// Author: Guru Pradeep Reddy, Bhanu Priya Sayal
+// Organization: FOSSEE, IIT Bombay
+// Email: gurupradeept@gmail.com, bhanupriyasayal@gmail.com
+// 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
+
+
+function [xopt,fopt,exitflag,output,lambda] = matrix_linprog (varargin)
+//To check the number of input and output argument
+ [lhs , rhs] = argn();
+
+ c = [];
+ A = [];
+ b = [];
+ Aeq = [];
+ beq = [];
+ lb = [];
+ ub = [];
+ options = list();
+
+//To check the number of argument given by user
+ if ( rhs < 3 | rhs == 4 | rhs == 6 | rhs >8 ) then
+ errmsg = msprintf(gettext("%s: Unexpected number of input arguments : %d provided while should be in the set of [3 5 7 8]"), "linprog", rhs);
+ error(errmsg)
+ end
+
+ c = varargin(1);
+
+ if (size(c,2)~=1) then
+ errmsg = msprintf(gettext("%s: Objective Coefficients should be a column matrix"), "linprog");
+ error(errmsg);
+ end
+
+ if(size(c,2) == 0) then
+ errmsg = msprintf(gettext("%s: Cannot determine the number of variables because input objective coefficients is empty"), "linprog");
+ error(errmsg);
+ end
+
+ nbVar = size(c,1);
+ A = varargin(2);
+ b = varargin(3);
+
+ if ( rhs<4 ) then
+ Aeq = []
+ beq = []
+ else
+ Aeq = varargin(4);
+ beq = varargin(5);
+ end
+
+ if ( rhs<6 ) then
+ lb = [];
+ ub = [];
+ else
+ lb = varargin(6);
+ ub = varargin(7);
+ end
+
+ if ( rhs<8 | size(varargin(8)) ==0 ) then
+ param = list();
+ else
+ param =varargin(8);
+ end
+
+ nbConInEq = size(A,1);
+ nbConEq = size(Aeq,1);
+
+ 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(lb,2)==0) then
+ lb = repmat(-%inf,nbVar,1);
+ end
+
+ if (size(ub,2)==0) then
+ ub = repmat(%inf,nbVar,1);
+ end
+
+ if (type(param) ~= 15) then
+ errmsg = msprintf(gettext("%s: options should be a list "), "linprog");
+ error(errmsg);
+ end
+
+
+ if (modulo(size(param),2)) then
+ errmsg = msprintf(gettext("%s: Size of parameters should be even"), "linprog");
+ error(errmsg);
+ end
+
+ options = list("MaxIter", [3000]);
+
+ for i = 1:(size(param))/2
+
+ select param(2*i-1)
+ case "MaxIter" then
+ options(2*i) = param(2*i);
+ else
+ errmsg = msprintf(gettext("%s: Unrecognized parameter name ''%s''."), "qpipoptmat", param(2*i-1));
+ 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 c"), "linprog");
+ 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 c"), "linprog");
+ 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"), "linprog");
+ 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"), "linprog");
+ 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,2) ~= 0) then
+ errmsg = msprintf(gettext("%s: The number of rows in A must be the same as the number of elements of b"), "linprog");
+ 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,2) ~= 0) then
+ errmsg = msprintf(gettext("%s: The number of rows in Aeq must be the same as the number of elements of beq"), "linprog");
+ error(errmsg);
+ end
+
+ //Check if the user gives a matrix instead of a vector
+
+ if (size(lb,1)~=1)& (size(lb,2)~=1) then
+ errmsg = msprintf(gettext("%s: Lower Bound should be a vector"), "linprog");
+ error(errmsg);
+ end
+
+ if (size(ub,1)~=1)& (size(ub,2)~=1) then
+ errmsg = msprintf(gettext("%s: Upper Bound should be a vector"), "linprog");
+ 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"), "linprog");
+ 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"), "linprog");
+ error(errmsg);
+ end
+ end
+
+ for i = 1:nbConInEq
+ if (b(i) == -%inf)
+ errmsg = msprintf(gettext("%s: Value of b can not be negative infinity"), "linprog");
+ error(errmsg);
+ end
+ end
+
+ for i = 1:nbConEq
+ if (beq(i) == -%inf)
+ errmsg = msprintf(gettext("%s: Value of beq can not be negative infinity"), "linprog");
+ error(errmsg);
+ end
+ end
+
+ lb = lb(:);
+ ub = ub(:)
+ b = b(:);
+ beq = beq(:);
+ nbVar = size(c,1);
+ c = c';
+ conMatrix = [Aeq;A];
+ nbCon = size(conMatrix,1);
+ conlb = [beq; repmat(-%inf,nbConInEq,1)];
+ conub = [beq;b];
+
+ [xopt,fopt,status,iter,Zl,dual] = linearprog(nbVar,nbCon,c,conMatrix,conlb,conub,lb',ub',options);
+
+ xopt = xopt';
+ exitflag = status;
+ output = struct("Iterations" , [],..
+ "constrviolation" , []);
+
+ output.Iterations = iter;
+ output.constrviolation = max([0;norm(Aeq*xopt-beq, 'inf');(lb-xopt);(xopt-ub);(A*xopt-b)]);
+ lambda = struct("reduced_cost" , [], ..
+ "ineqlin" , [], ..
+ "eqlin" , []);
+
+ lambda.reduced_cost = Zl;
+ lambda.eqlin = dual(1:nbConEq);
+ lambda.ineqlin = dual(nbConEq+1:nbCon);
+ select status
+
+ case 0 then
+ printf("\nOptimal Solution.\n");
+ case 1 then
+ printf("\nPrimal Infeasible.\n");
+ case 2 then
+ printf("\nDual Infeasible.\n");
+ case 3 then
+ printf("\nIteration limit reached.\n");
+ case 4 then
+ printf("\nNumerical Difficulties.\n");
+ case 5 then
+ printf("\nPrimal Objective limit reached.\n");
+ case 6 then
+ printf("\nDual Objective limit reached.\n");
+ else
+ printf("\nInvalid status returned. Notify the Toolbox authors\n");
+ break;
+ end
+
+endfunction