Home > matpower7.0 > lib > miqps_mosek.m

miqps_mosek

PURPOSE ^

MIQPS_MOSEK Mixed Integer Quadratic Program Solver based on MOSEK.

SYNOPSIS ^

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

DESCRIPTION ^

MIQPS_MOSEK  Mixed Integer Quadratic Program Solver based on MOSEK.
   [X, F, EXITFLAG, OUTPUT, LAMBDA] = ...
       MIQPS_MOSEK(H, C, A, L, U, XMIN, XMAX, X0, VTYPE, 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
       VTYPE : character string of length NX (number of elements in X),
               or 1 (value applies to all variables in x),
               allowed values are 'C' (continuous), 'B' (binary),
               'I' (integer).
       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
           skip_prices (0) - flag that specifies whether or not to
               skip the price computation stage, in which the problem
               is re-solved for only the continuous variables, with all
               others being constrained to their solved values
           price_stage_warn_tol (1e-7) - tolerance on the objective fcn
               value and primal variable relative match required to avoid
               mis-match warning message
           mosek_opt - options struct for MOSEK, value in verbose
               overrides 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, vtype, 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] = ...
           miqps_mosek(H, c, A, l, u, xmin, xmax, x0, vtype, opt)

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

   Example: (problem from from https://v8doc.sas.com/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] = miqps_mosek(H, c, A, l, u, xmin, [], x0, vtype, opt);

   See also MOSEKOPT.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [x, f, eflag, output, lambda] = miqps_mosek(H, c, A, l, u, xmin, xmax, x0, vtype, opt)
0002 %MIQPS_MOSEK  Mixed Integer Quadratic Program Solver based on MOSEK.
0003 %   [X, F, EXITFLAG, OUTPUT, LAMBDA] = ...
0004 %       MIQPS_MOSEK(H, C, A, L, U, XMIN, XMAX, X0, VTYPE, 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 %       VTYPE : character string of length NX (number of elements in X),
0026 %               or 1 (value applies to all variables in x),
0027 %               allowed values are 'C' (continuous), 'B' (binary),
0028 %               'I' (integer).
0029 %       OPT : optional options structure with the following fields,
0030 %           all of which are also optional (default values shown in
0031 %           parentheses)
0032 %           verbose (0) - controls level of progress output displayed
0033 %               0 = no progress output
0034 %               1 = some progress output
0035 %               2 = verbose progress output
0036 %           skip_prices (0) - flag that specifies whether or not to
0037 %               skip the price computation stage, in which the problem
0038 %               is re-solved for only the continuous variables, with all
0039 %               others being constrained to their solved values
0040 %           price_stage_warn_tol (1e-7) - tolerance on the objective fcn
0041 %               value and primal variable relative match required to avoid
0042 %               mis-match warning message
0043 %           mosek_opt - options struct for MOSEK, value in verbose
0044 %               overrides these options
0045 %       PROBLEM : The inputs can alternatively be supplied in a single
0046 %           PROBLEM struct with fields corresponding to the input arguments
0047 %           described above: H, c, A, l, u, xmin, xmax, x0, vtype, opt
0048 %
0049 %   Outputs:
0050 %       X : solution vector
0051 %       F : final objective function value
0052 %       EXITFLAG : exit flag
0053 %             1 = success
0054 %             0 = terminated at maximum number of iterations
0055 %            -1 = primal or dual infeasible
0056 %           < 0 = the negative of the MOSEK return code
0057 %       OUTPUT : output struct with the following fields:
0058 %           r - MOSEK return code
0059 %           res - MOSEK result struct
0060 %       LAMBDA : struct containing the Langrange and Kuhn-Tucker
0061 %           multipliers on the constraints, with fields:
0062 %           mu_l - lower (left-hand) limit on linear constraints
0063 %           mu_u - upper (right-hand) limit on linear constraints
0064 %           lower - lower bound on optimization variables
0065 %           upper - upper bound on optimization variables
0066 %
0067 %   Note the calling syntax is almost identical to that of QUADPROG
0068 %   from MathWorks' Optimization Toolbox. The main difference is that
0069 %   the linear constraints are specified with A, L, U instead of
0070 %   A, B, Aeq, Beq.
0071 %
0072 %   Calling syntax options:
0073 %       [x, f, exitflag, output, lambda] = ...
0074 %           miqps_mosek(H, c, A, l, u, xmin, xmax, x0, vtype, opt)
0075 %
0076 %       x = miqps_mosek(H, c, A, l, u)
0077 %       x = miqps_mosek(H, c, A, l, u, xmin, xmax)
0078 %       x = miqps_mosek(H, c, A, l, u, xmin, xmax, x0)
0079 %       x = miqps_mosek(H, c, A, l, u, xmin, xmax, x0, vtype)
0080 %       x = miqps_mosek(H, c, A, l, u, xmin, xmax, x0, vtype, opt)
0081 %       x = miqps_mosek(problem), where problem is a struct with fields:
0082 %                       H, c, A, l, u, xmin, xmax, x0, vtype, opt
0083 %                       all fields except 'c', 'A' and 'l' or 'u' are optional
0084 %       x = miqps_mosek(...)
0085 %       [x, f] = miqps_mosek(...)
0086 %       [x, f, exitflag] = miqps_mosek(...)
0087 %       [x, f, exitflag, output] = miqps_mosek(...)
0088 %       [x, f, exitflag, output, lambda] = miqps_mosek(...)
0089 %
0090 %   Example: (problem from from https://v8doc.sas.com/sashtml/iml/chap8/sect12.htm)
0091 %       H = [   1003.1  4.3     6.3     5.9;
0092 %               4.3     2.2     2.1     3.9;
0093 %               6.3     2.1     3.5     4.8;
0094 %               5.9     3.9     4.8     10  ];
0095 %       c = zeros(4,1);
0096 %       A = [   1       1       1       1;
0097 %               0.17    0.11    0.10    0.18    ];
0098 %       l = [1; 0.10];
0099 %       u = [1; Inf];
0100 %       xmin = zeros(4,1);
0101 %       x0 = [1; 0; 0; 1];
0102 %       opt = struct('verbose', 2);
0103 %       [x, f, s, out, lambda] = miqps_mosek(H, c, A, l, u, xmin, [], x0, vtype, opt);
0104 %
0105 %   See also MOSEKOPT.
0106 
0107 %   MATPOWER
0108 %   Copyright (c) 2010-2016, Power Systems Engineering Research Center (PSERC)
0109 %   by Ray Zimmerman, PSERC Cornell
0110 %
0111 %   This file is part of MATPOWER.
0112 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0113 %   See https://matpower.org for more info.
0114 
0115 %% check for Optimization Toolbox
0116 % if ~have_fcn('mosek')
0117 %     error('miqps_mosek: requires MOSEK');
0118 % end
0119 
0120 %%----- input argument handling  -----
0121 %% gather inputs
0122 if nargin == 1 && isstruct(H)       %% problem struct
0123     p = H;
0124 else                                %% individual args
0125     p = struct('H', H, 'c', c, 'A', A, 'l', l, 'u', u);
0126     if nargin > 5
0127         p.xmin = xmin;
0128         if nargin > 6
0129             p.xmax = xmax;
0130             if nargin > 7
0131                 p.x0 = x0;
0132                 if nargin > 8
0133                     p.vtype = vtype;
0134                     if nargin > 9
0135                         p.opt = opt;
0136                     end
0137                 end
0138             end
0139         end
0140     end
0141 end
0142 
0143 %% define nx, set default values for H and c
0144 if ~isfield(p, 'H') || isempty(p.H) || ~any(any(p.H))
0145     if (~isfield(p, 'A') || isempty(p.A)) && ...
0146             (~isfield(p, 'xmin') || isempty(p.xmin)) && ...
0147             (~isfield(p, 'xmax') || isempty(p.xmax))
0148         error('miqps_mosek: LP problem must include constraints or variable bounds');
0149     else
0150         if isfield(p, 'A') && ~isempty(p.A)
0151             nx = size(p.A, 2);
0152         elseif isfield(p, 'xmin') && ~isempty(p.xmin)
0153             nx = length(p.xmin);
0154         else    % if isfield(p, 'xmax') && ~isempty(p.xmax)
0155             nx = length(p.xmax);
0156         end
0157     end
0158     p.H = sparse(nx, nx);
0159     qp = 0;
0160 else
0161     nx = size(p.H, 1);
0162     qp = 1;
0163 end
0164 if ~isfield(p, 'c') || isempty(p.c)
0165     p.c = zeros(nx, 1);
0166 end
0167 if ~isfield(p, 'x0') || isempty(p.x0)
0168     p.x0 = zeros(nx, 1);
0169 end
0170 if ~isfield(p, 'vtype') || isempty(p.vtype)
0171     p.vtype = '';
0172 end
0173 
0174 %% default options
0175 if ~isfield(p, 'opt')
0176     p.opt = [];
0177 end
0178 if ~isempty(p.opt) && isfield(p.opt, 'verbose') && ~isempty(p.opt.verbose)
0179     verbose = p.opt.verbose;
0180 else
0181     verbose = 0;
0182 end
0183 if ~isempty(p.opt) && isfield(p.opt, 'mosek_opt') && ~isempty(p.opt.mosek_opt)
0184     mosek_opt = mosek_options(p.opt.mosek_opt);
0185 else
0186     mosek_opt = mosek_options;
0187 end
0188 
0189 %% set up problem struct for MOSEK
0190 prob.c = p.c;
0191 if qp
0192    [prob.qosubi, prob.qosubj, prob.qoval] = find(tril(sparse(p.H)));
0193 end
0194 if isfield(p, 'A') && ~isempty(p.A)
0195     prob.a = sparse(p.A);
0196     nA = size(p.A, 1);
0197 else
0198     nA = 0;
0199 end
0200 if isfield(p, 'l') && ~isempty(p.A)
0201     prob.blc = p.l;
0202 end
0203 if isfield(p, 'u') && ~isempty(p.A)
0204     prob.buc = p.u;
0205 end
0206 if ~isempty(p.vtype)
0207     if length(p.vtype) == 1
0208         if p.vtype == 'I'
0209             prob.ints.sub = (1:nx);
0210         elseif p.vtype == 'B'
0211             prob.ints.sub = (1:nx);
0212             p.xmin = zeros(nx, 1);
0213             p.xmax = ones(nx, 1);
0214         end
0215     else
0216         k = find(p.vtype == 'B' | p.vtype == 'I');
0217         prob.ints.sub = k;
0218         k = find(p.vtype == 'B');
0219         if ~isempty(k)
0220             if isempty(p.xmin)
0221                 p.xmin = -Inf(nx, 1);
0222             end
0223             if isempty(p.xmax)
0224                 p.xmax = Inf(nx, 1);
0225             end
0226             p.xmin(k) = 0;
0227             p.xmax(k) = 1;
0228         end
0229     end
0230 end
0231 if isfield(p, 'xmin') && ~isempty(p.xmin)
0232     prob.blx = p.xmin;
0233 end
0234 if isfield(p, 'xmax') && ~isempty(p.xmax)
0235     prob.bux = p.xmax;
0236 end
0237 
0238 %% A is not allowed to be empty
0239 if ~isfield(prob, 'a') || isempty(prob.a)
0240     unconstrained = 1;
0241     prob.a = sparse(1, 1, 1, 1, nx);
0242     prob.blc = -Inf;
0243     prob.buc =  Inf;
0244 else
0245     unconstrained = 0;
0246 end
0247 sc = mosek_symbcon;
0248 s = have_fcn('mosek', 'all');
0249 if isfield(prob, 'ints') && isfield(prob.ints, 'sub') && ~isempty(prob.ints.sub)
0250     mi = 1;
0251     if s.vnum >= 8
0252         mosek_opt.MSK_IPAR_OPTIMIZER = sc.MSK_OPTIMIZER_MIXED_INT;
0253 %     else
0254 %         mosek_opt.MSK_IPAR_OPTIMIZER = sc.MSK_OPTIMIZER_MIXED_INT_CONIC;
0255     end
0256 else
0257     mi = 0;
0258 end
0259 
0260 %%-----  run optimization  -----
0261 if verbose
0262     if s.vnum < 7
0263         alg_names = {           %% version 6.x
0264             'default',              %%  0 : MSK_OPTIMIZER_FREE
0265             'interior point',       %%  1 : MSK_OPTIMIZER_INTPNT
0266             '<conic>',              %%  2 : MSK_OPTIMIZER_CONIC
0267             '<qcone>',              %%  3 : MSK_OPTIMIZER_QCONE
0268             'primal simplex',       %%  4 : MSK_OPTIMIZER_PRIMAL_SIMPLEX
0269             'dual simplex',         %%  5 : MSK_OPTIMIZER_DUAL_SIMPLEX
0270             'primal dual simplex',  %%  6 : MSK_OPTIMIZER_PRIMAL_DUAL_SIMPLEX
0271             'automatic simplex',    %%  7 : MSK_OPTIMIZER_FREE_SIMPLEX
0272             '<mixed int>',          %%  8 : MSK_OPTIMIZER_MIXED_INT
0273             '<nonconvex>',          %%  9 : MSK_OPTIMIZER_NONCONVEX
0274             'concurrent'            %% 10 : MSK_OPTIMIZER_CONCURRENT
0275         };
0276     elseif s.vnum < 8
0277         alg_names = {           %% version 7.x
0278             'default',              %%  0 : MSK_OPTIMIZER_FREE
0279             'interior point',       %%  1 : MSK_OPTIMIZER_INTPNT
0280             '<conic>',              %%  2 : MSK_OPTIMIZER_CONIC
0281             'primal simplex',       %%  3 : MSK_OPTIMIZER_PRIMAL_SIMPLEX
0282             'dual simplex',         %%  4 : MSK_OPTIMIZER_DUAL_SIMPLEX
0283             'primal dual simplex',  %%  5 : MSK_OPTIMIZER_PRIMAL_DUAL_SIMPLEX
0284             'automatic simplex',    %%  6 : MSK_OPTIMIZER_FREE_SIMPLEX
0285             'network simplex',      %%  7 : MSK_OPTIMIZER_NETWORK_PRIMAL_SIMPLEX
0286             '<mixed int conic>',    %%  8 : MSK_OPTIMIZER_MIXED_INT_CONIC
0287             '<mixed int>',          %%  9 : MSK_OPTIMIZER_MIXED_INT
0288             'concurrent',           %% 10 : MSK_OPTIMIZER_CONCURRENT
0289             '<nonconvex>'           %% 11 : MSK_OPTIMIZER_NONCONVEX
0290         };
0291     else
0292         alg_names = {           %% version 8.x
0293             '<conic>',              %%  0 : MSK_OPTIMIZER_CONIC
0294             'dual simplex',         %%  1 : MSK_OPTIMIZER_DUAL_SIMPLEX
0295             'default',              %%  2 : MSK_OPTIMIZER_FREE
0296             'automatic simplex',    %%  3 : MSK_OPTIMIZER_FREE_SIMPLEX
0297             'interior point',       %%  4 : MSK_OPTIMIZER_INTPNT
0298             '<mixed int>',          %%  5 : MSK_OPTIMIZER_MIXED_INT
0299             'primal simplex'        %%  6 : MSK_OPTIMIZER_PRIMAL_SIMPLEX
0300         };
0301     end
0302     if qp
0303         lpqp = 'QP';
0304     else
0305         lpqp = 'LP';
0306     end
0307     if mi
0308         lpqp = ['MI' lpqp];
0309     end
0310     vn = have_fcn('mosek', 'vstr');
0311     if isempty(vn)
0312         vn = '<unknown>';
0313     end
0314     fprintf('MOSEK Version %s -- %s %s solver\n', ...
0315             vn, alg_names{mosek_opt.MSK_IPAR_OPTIMIZER+1}, lpqp);
0316 end
0317 cmd = sprintf('minimize echo(%d)', verbose);
0318 [r, res] = mosekopt(cmd, prob, mosek_opt);
0319 
0320 %%-----  repackage results  -----
0321 if isfield(res, 'sol')
0322     if isfield(res.sol, 'int')
0323         sol = res.sol.int;
0324     elseif isfield(res.sol, 'bas')
0325         sol = res.sol.bas;
0326     else
0327         sol = res.sol.itr;
0328     end
0329     x = sol.xx;
0330 else
0331     sol = [];
0332     x = NaN(nx, 1);
0333 end
0334 
0335 %%-----  process return codes  -----
0336 eflag = -r;
0337 msg = '';
0338 switch (r)
0339     case sc.MSK_RES_OK
0340         if ~isempty(sol)
0341 %            if sol.solsta == sc.MSK_SOL_STA_OPTIMAL
0342             if strcmp(sol.solsta, 'OPTIMAL') || strcmp(sol.solsta, 'INTEGER_OPTIMAL')
0343                 msg = 'The solution is optimal.';
0344                 eflag = 1;
0345             else
0346                 eflag = -1;
0347 %                 if sol.prosta == sc.MSK_PRO_STA_PRIM_INFEAS
0348                 if strcmp(sol.prosta, 'PRIMAL_INFEASIBLE')
0349                     msg = 'The problem is primal infeasible.';
0350 %                 elseif sol.prosta == sc.MSK_PRO_STA_DUAL_INFEAS
0351                 elseif strcmp(sol.prosta, 'DUAL_INFEASIBLE')
0352                     msg = 'The problem is dual infeasible.';
0353                 else
0354                     msg = sol.solsta;
0355                 end
0356             end
0357         end
0358     case sc.MSK_RES_TRM_STALL
0359         if strcmp(sol.solsta, 'OPTIMAL') || strcmp(sol.solsta, 'INTEGER_OPTIMAL')
0360             msg = 'Stalled at or near optimal solution.';
0361             eflag = 1;
0362         else
0363             msg = 'Stalled.';
0364         end
0365     case sc.MSK_RES_TRM_MAX_ITERATIONS
0366         eflag = 0;
0367         msg = 'The optimizer terminated at the maximum number of iterations.';
0368     otherwise
0369         if isfield(res, 'rmsg') && isfield(res, 'rcodestr')
0370             msg = sprintf('%s : %s', res.rcodestr, res.rmsg);
0371         else
0372             msg = sprintf('MOSEK return code = %d', r);
0373         end
0374 end
0375 
0376 if (verbose || r == sc.MSK_RES_ERR_LICENSE || ...
0377         r == sc.MSK_RES_ERR_LICENSE_EXPIRED || ...
0378         r == sc.MSK_RES_ERR_LICENSE_VERSION || ...
0379         r == sc.MSK_RES_ERR_LICENSE_NO_SERVER_SUPPORT || ...
0380         r == sc.MSK_RES_ERR_LICENSE_FEATURE || ...
0381         r == sc.MSK_RES_ERR_LICENSE_INVALID_HOSTID || ...
0382         r == sc.MSK_RES_ERR_LICENSE_SERVER_VERSION || ...
0383         r == sc.MSK_RES_ERR_MISSING_LICENSE_FILE) ...
0384         && ~isempty(msg)  %% always alert user of license problems
0385     fprintf('%s\n', msg);
0386 end
0387 
0388 %%-----  repackage results  -----
0389 if nargout > 1
0390     if r == 0
0391         f = p.c' * x;
0392         if ~isempty(p.H)
0393             f = 0.5 * x' * p.H * x + f;
0394         end
0395     else
0396         f = [];
0397     end
0398     if nargout > 3
0399         output.r = r;
0400         output.res = res;
0401         if nargout > 4
0402             if ~isempty(sol)
0403                 if isfield(sol, 'slx')
0404                     lambda.lower = sol.slx;
0405                 else
0406                     lambda.lower = [];
0407                 end
0408                 if isfield(sol, 'sux')
0409                     lambda.upper = sol.sux;
0410                 else
0411                     lambda.upper = [];
0412                 end
0413                 if isfield(sol, 'slc')
0414                     lambda.mu_l  = sol.slc;
0415                 else
0416                     lambda.mu_l  = [];
0417                 end
0418                 if isfield(sol, 'suc')
0419                     lambda.mu_u  = sol.suc;
0420                 else
0421                     lambda.mu_u  = [];
0422                 end
0423             else
0424                 if isfield(p, 'xmin') && ~isempty(p.xmin)
0425                     lambda.lower = NaN(nx, 1);
0426                 else
0427                     lambda.lower = [];
0428                 end
0429                 if isfield(p, 'xmax') && ~isempty(p.xmax)
0430                     lambda.upper = NaN(nx, 1);
0431                 else
0432                     lambda.upper = [];
0433                 end
0434                 lambda.mu_l = NaN(nA, 1);
0435                 lambda.mu_u = NaN(nA, 1);
0436             end
0437             if unconstrained
0438                 lambda.mu_l  = [];
0439                 lambda.mu_u  = [];
0440             end
0441         end
0442     end
0443 end
0444 
0445 if mi && eflag == 1 && (~isfield(p.opt, 'skip_prices') || ~p.opt.skip_prices)
0446     if verbose
0447         fprintf('--- Integer stage complete, starting price computation stage ---\n');
0448     end
0449     if isfield(p.opt, 'price_stage_warn_tol') && ~isempty(p.opt.price_stage_warn_tol)
0450         tol = p.opt.price_stage_warn_tol;
0451     else
0452         tol = 1e-7;
0453     end
0454     pp = p;
0455     x(prob.ints.sub) = round(x(prob.ints.sub));
0456     pp.xmin(prob.ints.sub) = x(prob.ints.sub);
0457     pp.xmax(prob.ints.sub) = x(prob.ints.sub);
0458     pp.x0 = x;
0459     if qp
0460         pp.opt.mosek_opt.MSK_IPAR_OPTIMIZER = sc.MSK_OPTIMIZER_FREE;
0461     else
0462         pp.opt.mosek_opt.MSK_IPAR_OPTIMIZER = sc.MSK_OPTIMIZER_PRIMAL_SIMPLEX;
0463     end
0464     [x_, f_, eflag_, output_, lambda] = qps_mosek(pp);
0465     if eflag ~= eflag_
0466         error('miqps_mosek: EXITFLAG from price computation stage = %d', eflag_);
0467     end
0468     if abs(f - f_)/max(abs(f), 1) > tol
0469         warning('miqps_mosek: relative mismatch in objective function value from price computation stage = %g', abs(f - f_)/max(abs(f), 1));
0470     end
0471     xn = x;
0472     xn(abs(xn)<1) = 1;
0473     [mx, k] = max(abs(x - x_) ./ xn);
0474     if mx > tol
0475         warning('miqps_mosek: max relative mismatch in x from price computation stage = %g (%g)', mx, x(k));
0476     end
0477     output.price_stage = output_;
0478 end

Generated on Mon 24-Jun-2019 15:58:45 by m2html © 2005