Home > matpower4.1 > qps_mosek.m

qps_mosek

PURPOSE ^

QPS_MOSEK Quadratic Program Solver based on MOSEK.

SYNOPSIS ^

function [x, f, eflag, output, lambda] = qps_mosek(H, c, A, l, u, xmin, xmax, x0, opt)

DESCRIPTION ^

QPS_MOSEK  Quadratic Program Solver based on MOSEK.
   [X, F, EXITFLAG, OUTPUT, LAMBDA] = ...
       QPS_MOSEK(H, C, A, L, U, XMIN, XMAX, X0, OPT)
   A wrapper function providing a MATPOWER standardized interface for using
   MOSEKOPT to solve the following QP (quadratic programming) problem:

       min 1/2 X'*H*X + C'*X
        X

   subject to

       L <= A*X <= U       (linear constraints)
       XMIN <= X <= XMAX   (variable bounds)

   Inputs (all optional except H, C, A and L):
       H : matrix (possibly sparse) of quadratic cost coefficients
       C : vector of linear cost coefficients
       A, L, U : define the optional linear constraints. Default
           values for the elements of L and U are -Inf and Inf,
           respectively.
       XMIN, XMAX : optional lower and upper bounds on the
           X variables, defaults are -Inf and Inf, respectively.
       X0 : optional starting value of optimization vector X
       OPT : optional options structure with the following fields,
           all of which are also optional (default values shown in
           parentheses)
           verbose (0) - controls level of progress output displayed
               0 = no progress output
               1 = some progress output
               2 = verbose progress output
           max_it (0) - maximum number of iterations allowed
               0 = use algorithm default
           mosek_opt - options struct for MOSEK, values in
               verbose and max_it override these options
       PROBLEM : The inputs can alternatively be supplied in a single
           PROBLEM struct with fields corresponding to the input arguments
           described above: H, c, A, l, u, xmin, xmax, x0, opt

   Outputs:
       X : solution vector
       F : final objective function value
       EXITFLAG : exit flag
             1 = success
             0 = terminated at maximum number of iterations
            -1 = primal or dual infeasible
           < 0 = the negative of the MOSEK return code
       OUTPUT : output struct with the following fields:
           r - MOSEK return code
           res - MOSEK result struct
       LAMBDA : struct containing the Langrange and Kuhn-Tucker
           multipliers on the constraints, with fields:
           mu_l - lower (left-hand) limit on linear constraints
           mu_u - upper (right-hand) limit on linear constraints
           lower - lower bound on optimization variables
           upper - upper bound on optimization variables

   Note the calling syntax is almost identical to that of QUADPROG
   from MathWorks' Optimization Toolbox. The main difference is that
   the linear constraints are specified with A, L, U instead of
   A, B, Aeq, Beq.

   Calling syntax options:
       [x, f, exitflag, output, lambda] = ...
           qps_mosek(H, c, A, l, u, xmin, xmax, x0, opt)

       x = qps_mosek(H, c, A, l, u)
       x = qps_mosek(H, c, A, l, u, xmin, xmax)
       x = qps_mosek(H, c, A, l, u, xmin, xmax, x0)
       x = qps_mosek(H, c, A, l, u, xmin, xmax, x0, opt)
       x = qps_mosek(problem), where problem is a struct with fields:
                       H, c, A, l, u, xmin, xmax, x0, opt
                       all fields except 'c', 'A' and 'l' or 'u' are optional
       x = qps_mosek(...)
       [x, f] = qps_mosek(...)
       [x, f, exitflag] = qps_mosek(...)
       [x, f, exitflag, output] = qps_mosek(...)
       [x, f, exitflag, output, lambda] = qps_mosek(...)

   Example: (problem from from http://www.jmu.edu/docs/sasdoc/sashtml/iml/chap8/sect12.htm)
       H = [   1003.1  4.3     6.3     5.9;
               4.3     2.2     2.1     3.9;
               6.3     2.1     3.5     4.8;
               5.9     3.9     4.8     10  ];
       c = zeros(4,1);
       A = [   1       1       1       1;
               0.17    0.11    0.10    0.18    ];
       l = [1; 0.10];
       u = [1; Inf];
       xmin = zeros(4,1);
       x0 = [1; 0; 0; 1];
       opt = struct('verbose', 2);
       [x, f, s, out, lambda] = qps_mosek(H, c, A, l, u, xmin, [], x0, opt);

   See also MOSEKOPT.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [x, f, eflag, output, lambda] = qps_mosek(H, c, A, l, u, xmin, xmax, x0, opt)
0002 %QPS_MOSEK  Quadratic Program Solver based on MOSEK.
0003 %   [X, F, EXITFLAG, OUTPUT, LAMBDA] = ...
0004 %       QPS_MOSEK(H, C, A, L, U, XMIN, XMAX, X0, OPT)
0005 %   A wrapper function providing a MATPOWER standardized interface for using
0006 %   MOSEKOPT to solve the following QP (quadratic programming) problem:
0007 %
0008 %       min 1/2 X'*H*X + C'*X
0009 %        X
0010 %
0011 %   subject to
0012 %
0013 %       L <= A*X <= U       (linear constraints)
0014 %       XMIN <= X <= XMAX   (variable bounds)
0015 %
0016 %   Inputs (all optional except H, C, A and L):
0017 %       H : matrix (possibly sparse) of quadratic cost coefficients
0018 %       C : vector of linear cost coefficients
0019 %       A, L, U : define the optional linear constraints. Default
0020 %           values for the elements of L and U are -Inf and Inf,
0021 %           respectively.
0022 %       XMIN, XMAX : optional lower and upper bounds on the
0023 %           X variables, defaults are -Inf and Inf, respectively.
0024 %       X0 : optional starting value of optimization vector X
0025 %       OPT : optional options structure with the following fields,
0026 %           all of which are also optional (default values shown in
0027 %           parentheses)
0028 %           verbose (0) - controls level of progress output displayed
0029 %               0 = no progress output
0030 %               1 = some progress output
0031 %               2 = verbose progress output
0032 %           max_it (0) - maximum number of iterations allowed
0033 %               0 = use algorithm default
0034 %           mosek_opt - options struct for MOSEK, values in
0035 %               verbose and max_it override these options
0036 %       PROBLEM : The inputs can alternatively be supplied in a single
0037 %           PROBLEM struct with fields corresponding to the input arguments
0038 %           described above: H, c, A, l, u, xmin, xmax, x0, opt
0039 %
0040 %   Outputs:
0041 %       X : solution vector
0042 %       F : final objective function value
0043 %       EXITFLAG : exit flag
0044 %             1 = success
0045 %             0 = terminated at maximum number of iterations
0046 %            -1 = primal or dual infeasible
0047 %           < 0 = the negative of the MOSEK return code
0048 %       OUTPUT : output struct with the following fields:
0049 %           r - MOSEK return code
0050 %           res - MOSEK result struct
0051 %       LAMBDA : struct containing the Langrange and Kuhn-Tucker
0052 %           multipliers on the constraints, with fields:
0053 %           mu_l - lower (left-hand) limit on linear constraints
0054 %           mu_u - upper (right-hand) limit on linear constraints
0055 %           lower - lower bound on optimization variables
0056 %           upper - upper bound on optimization variables
0057 %
0058 %   Note the calling syntax is almost identical to that of QUADPROG
0059 %   from MathWorks' Optimization Toolbox. The main difference is that
0060 %   the linear constraints are specified with A, L, U instead of
0061 %   A, B, Aeq, Beq.
0062 %
0063 %   Calling syntax options:
0064 %       [x, f, exitflag, output, lambda] = ...
0065 %           qps_mosek(H, c, A, l, u, xmin, xmax, x0, opt)
0066 %
0067 %       x = qps_mosek(H, c, A, l, u)
0068 %       x = qps_mosek(H, c, A, l, u, xmin, xmax)
0069 %       x = qps_mosek(H, c, A, l, u, xmin, xmax, x0)
0070 %       x = qps_mosek(H, c, A, l, u, xmin, xmax, x0, opt)
0071 %       x = qps_mosek(problem), where problem is a struct with fields:
0072 %                       H, c, A, l, u, xmin, xmax, x0, opt
0073 %                       all fields except 'c', 'A' and 'l' or 'u' are optional
0074 %       x = qps_mosek(...)
0075 %       [x, f] = qps_mosek(...)
0076 %       [x, f, exitflag] = qps_mosek(...)
0077 %       [x, f, exitflag, output] = qps_mosek(...)
0078 %       [x, f, exitflag, output, lambda] = qps_mosek(...)
0079 %
0080 %   Example: (problem from from http://www.jmu.edu/docs/sasdoc/sashtml/iml/chap8/sect12.htm)
0081 %       H = [   1003.1  4.3     6.3     5.9;
0082 %               4.3     2.2     2.1     3.9;
0083 %               6.3     2.1     3.5     4.8;
0084 %               5.9     3.9     4.8     10  ];
0085 %       c = zeros(4,1);
0086 %       A = [   1       1       1       1;
0087 %               0.17    0.11    0.10    0.18    ];
0088 %       l = [1; 0.10];
0089 %       u = [1; Inf];
0090 %       xmin = zeros(4,1);
0091 %       x0 = [1; 0; 0; 1];
0092 %       opt = struct('verbose', 2);
0093 %       [x, f, s, out, lambda] = qps_mosek(H, c, A, l, u, xmin, [], x0, opt);
0094 %
0095 %   See also MOSEKOPT.
0096 
0097 %   MATPOWER
0098 %   $Id: qps_mosek.m,v 1.5 2011/09/09 15:26:08 cvs Exp $
0099 %   by Ray Zimmerman, PSERC Cornell
0100 %   Copyright (c) 2010 by Power System Engineering Research Center (PSERC)
0101 %
0102 %   This file is part of MATPOWER.
0103 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0104 %
0105 %   MATPOWER is free software: you can redistribute it and/or modify
0106 %   it under the terms of the GNU General Public License as published
0107 %   by the Free Software Foundation, either version 3 of the License,
0108 %   or (at your option) any later version.
0109 %
0110 %   MATPOWER is distributed in the hope that it will be useful,
0111 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0112 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0113 %   GNU General Public License for more details.
0114 %
0115 %   You should have received a copy of the GNU General Public License
0116 %   along with MATPOWER. If not, see <http://www.gnu.org/licenses/>.
0117 %
0118 %   Additional permission under GNU GPL version 3 section 7
0119 %
0120 %   If you modify MATPOWER, or any covered work, to interface with
0121 %   other modules (such as MATLAB code and MEX-files) available in a
0122 %   MATLAB(R) or comparable environment containing parts covered
0123 %   under other licensing terms, the licensors of MATPOWER grant
0124 %   you additional permission to convey the resulting work.
0125 
0126 %% check for Optimization Toolbox
0127 % if ~have_fcn('mosek')
0128 %     error('qps_mosek: requires MOSEK');
0129 % end
0130 
0131 %%----- input argument handling  -----
0132 %% gather inputs
0133 if nargin == 1 && isstruct(H)       %% problem struct
0134     p = H;
0135 else                                %% individual args
0136     p = struct('H', H, 'c', c, 'A', A, 'l', l, 'u', u);
0137     if nargin > 5
0138         p.xmin = xmin;
0139         if nargin > 6
0140             p.xmax = xmax;
0141             if nargin > 7
0142                 p.x0 = x0;
0143                 if nargin > 8
0144                     p.opt = opt;
0145                 end
0146             end
0147         end
0148     end
0149 end
0150 
0151 %% define nx, set default values for H and c
0152 if ~isfield(p, 'H') || isempty(p.H) || ~any(any(p.H))
0153     if (~isfield(p, 'A') || isempty(p.A)) && ...
0154             (~isfield(p, 'xmin') || isempty(p.xmin)) && ...
0155             (~isfield(p, 'xmax') || isempty(p.xmax))
0156         error('qps_mosek: LP problem must include constraints or variable bounds');
0157     else
0158         if isfield(p, 'A') && ~isempty(p.A)
0159             nx = size(p.A, 2);
0160         elseif isfield(p, 'xmin') && ~isempty(p.xmin)
0161             nx = length(p.xmin);
0162         else    % if isfield(p, 'xmax') && ~isempty(p.xmax)
0163             nx = length(p.xmax);
0164         end
0165     end
0166     p.H = sparse(nx, nx);
0167     qp = 0;
0168 else
0169     nx = size(p.H, 1);
0170     qp = 1;
0171 end
0172 if ~isfield(p, 'c') || isempty(p.c)
0173     p.c = zeros(nx, 1);
0174 end
0175 if ~isfield(p, 'x0') || isempty(p.x0)
0176     p.x0 = zeros(nx, 1);
0177 end
0178 
0179 %% default options
0180 if ~isfield(p, 'opt')
0181     p.opt = [];
0182 end
0183 if ~isempty(p.opt) && isfield(p.opt, 'verbose') && ~isempty(p.opt.verbose)
0184     verbose = p.opt.verbose;
0185 else
0186     verbose = 0;
0187 end
0188 if ~isempty(p.opt) && isfield(p.opt, 'max_it') && ~isempty(p.opt.max_it)
0189     max_it = p.opt.max_it;
0190 else
0191     max_it = 0;
0192 end
0193 if ~isempty(p.opt) && isfield(p.opt, 'mosek_opt') && ~isempty(p.opt.mosek_opt)
0194     mosek_opt = mosek_options(p.opt.mosek_opt);
0195 else
0196     mosek_opt = mosek_options;
0197 end
0198 if max_it
0199     mosek_opt.MSK_IPAR_INTPNT_MAX_ITERATIONS = max_it;
0200 end
0201 if qp
0202     mosek_opt.MSK_IPAR_OPTIMIZER = 0;   %% default solver only for QP
0203 end
0204 
0205 %% set up problem struct for MOSEK
0206 prob.c = p.c;
0207 if qp
0208    [prob.qosubi, prob.qosubj, prob.qoval] = find(tril(sparse(p.H)));
0209 end
0210 if isfield(p, 'A') && ~isempty(p.A)
0211     prob.a = sparse(p.A);
0212 end
0213 if isfield(p, 'l') && ~isempty(p.A)
0214     prob.blc = p.l;
0215 end
0216 if isfield(p, 'u') && ~isempty(p.A)
0217     prob.buc = p.u;
0218 end
0219 if isfield(p, 'xmin') && ~isempty(p.xmin)
0220     prob.blx = p.xmin;
0221 end
0222 if isfield(p, 'xmax') && ~isempty(p.xmax)
0223     prob.bux = p.xmax;
0224 end
0225 
0226 %% A is not allowed to be empty
0227 if ~isfield(prob, 'a') || isempty(prob.a)
0228     unconstrained = 1;
0229     prob.a = sparse(1, 1, 1, 1, nx);
0230     prob.blc = -Inf;
0231     prob.buc =  Inf;
0232 else
0233     unconstrained = 0;
0234 end
0235 
0236 %%-----  run optimization  -----
0237 if verbose
0238     methods = {
0239         'default',
0240         'interior point',
0241         '<default>',
0242         '<default>',
0243         'primal simplex',
0244         'dual simplex',
0245         'primal dual simplex',
0246         'automatic simplex',
0247         '<default>',
0248         '<default>',
0249         'concurrent'
0250     };
0251     if isempty(H) || ~any(any(H))
0252         lpqp = 'LP';
0253     else
0254         lpqp = 'QP';
0255     end
0256     % (this code is also in mpver.m)
0257     % MOSEK Version 6.0.0.93 (Build date: 2010-10-26 13:03:27)
0258     % MOSEK Version 6.0.0.106 (Build date: 2011-3-17 10:46:54)
0259 %    pat = 'Version (\.*\d)+.*Build date: (\d\d\d\d-\d\d-\d\d)';
0260     pat = 'Version (\.*\d)+.*Build date: (\d+-\d+-\d+)';
0261     [s,e,tE,m,t] = regexp(evalc('mosekopt'), pat);
0262     if isempty(t)
0263         vn = '<unknown>';
0264     else
0265         vn = t{1}{1};
0266     end
0267     fprintf('MOSEK Version %s -- %s %s solver\n', ...
0268             vn, methods{mosek_opt.MSK_IPAR_OPTIMIZER+1}, lpqp);
0269 end
0270 cmd = sprintf('minimize echo(%d)', verbose);
0271 [r, res] = mosekopt(cmd, prob, mosek_opt);
0272 
0273 %%-----  repackage results  -----
0274 if isfield(res, 'sol')
0275     if isfield(res.sol, 'bas')
0276         sol = res.sol.bas;
0277     else
0278         sol = res.sol.itr;
0279     end
0280     x = sol.xx;
0281 else
0282     sol = [];
0283     x = [];
0284 end
0285 
0286 %%-----  process return codes  -----
0287 if isfield(res, 'symbcon')
0288     sc = res.symbcon;
0289 else    
0290     [r2, res2] = mosekopt('symbcon echo(0)');
0291     sc = res2.symbcon;
0292 end
0293 eflag = -r;
0294 msg = '';
0295 switch (r)
0296     case sc.MSK_RES_OK
0297         if ~isempty(sol)
0298 %            if sol.solsta == sc.MSK_SOL_STA_OPTIMAL
0299             if strcmp(sol.solsta, 'OPTIMAL')
0300                 msg = 'The solution is optimal.';
0301                 eflag = 1;
0302             else
0303                 eflag = -1;
0304 %                 if sol.prosta == sc.MSK_PRO_STA_PRIM_INFEAS
0305                 if strcmp(sol.prosta, 'PRIMAL_INFEASIBLE')
0306                     msg = 'The problem is primal infeasible.';
0307 %                 elseif sol.prosta == sc.MSK_PRO_STA_DUAL_INFEAS
0308                 elseif strcmp(sol.prosta, 'DUAL_INFEASIBLE')
0309                     msg = 'The problem is dual infeasible.';
0310                 else
0311                     msg = sol.solsta;
0312                 end
0313             end
0314         end
0315     case sc.MSK_RES_TRM_MAX_ITERATIONS
0316         eflag = 0;
0317         msg = 'The optimizer terminated at the maximum number of iterations.';
0318     otherwise
0319         if isfield(res, 'rmsg') && isfield(res, 'rcodestr')
0320             msg = sprintf('%s : %s', res.rcodestr, res.rmsg);
0321         else
0322             msg = sprintf('MOSEK return code = %d', r);
0323         end
0324 end
0325 
0326 if (verbose || r == 1001) && ~isempty(msg)  %% always alert user if license is expired
0327     fprintf('%s\n', msg);
0328 end
0329 
0330 %%-----  repackage results  -----
0331 if nargout > 1
0332     if r == 0
0333         f = p.c' * x;
0334         if ~isempty(p.H)
0335             f = 0.5 * x' * p.H * x + f;
0336         end
0337     else
0338         f = [];
0339     end
0340     if nargout > 3
0341         output.r = r;
0342         output.res = res;
0343         if nargout > 4
0344             if isfield(res, 'sol')
0345                 lambda.lower = sol.slx;
0346                 lambda.upper = sol.sux;
0347                 lambda.mu_l  = sol.slc;
0348                 lambda.mu_u  = sol.suc;
0349                 if unconstrained
0350                     lambda.mu_l  = [];
0351                     lambda.mu_u  = [];
0352                 end
0353             else
0354                 lambda = [];
0355             end
0356         end
0357     end
0358 end

Generated on Mon 26-Jan-2015 15:00:13 by m2html © 2005