SOLVE Solve the optimization model. X = OM.SOLVE() [X, F] = OM.SOLVE() [X, F, EXITFLAG] = OM.SOLVE() [X, F, EXITFLAG, OUTPUT] = OM.SOLVE() [X, F, EXITFLAG, OUTPUT, JAC] = OM.SOLVE() (NLEQ problems) [X, F, EXITFLAG, OUTPUT, LAMBDA] = OM.SOLVE() (other problem types) [X ...] = OM.SOLVE(OPT) Solves the optimization model using one of the following, depending on the problem type: QPS_MASTER, MIQPS_MASTER, NLPS_MASTER, NLEQS_MASTER. Inputs: OPT : optional options structure with the following fields, all of which are also optional (default values shown in parentheses) alg ('DEFAULT') : determines which solver to use, list of relevant problem types are listed in parens next to each 'DEFAULT' : automatic, depending on problem type, uses the the first available of: LP - Gurobi, CPLEX, MOSEK, linprog (if MATLAB), GLPK, BPMPD, MIPS QP - Gurobi, CPLEX, MOSEK, quadprog (if MATLAB), BPMPD, MIPS MILP - Gurobi, CPLEX, MOSEK, Opt Tbx (intlingprog), GLPK MIQP - Gurobi, CPLEX, MOSEK NLP - MIPS MINLP - Artelys Knitro (not yet implemented) NLEQ - Newton's method 'BPMPD' : (LP, QP) BPMPD_MEX 'CLP' : (LP, QP) CLP 'CPLEX' : (LP, QP, MILP, MIQP) CPLEX 'FD' : (NLEQ) fast-decoupled Newon's method 'FMINCON' : (NLP) FMINCON, MATLAB Optimization Toolbox 'FSOLVE' : (NLEQ) FSOLVE, MATLAB Optimization Toolbox 'GLPK' : (LP, MILP) GLPK 'GS' : (NLEQ) Gauss-Seidel 'GUROBI' : (LP, QP, MILP, MIQP) Gurobi 'IPOPT' : (LP, QP, NLP) IPOPT, requires MEX interface to IPOPT solver https://github.com/coin-or/Ipopt 'KNITRO' : (NLP, MINLP) Artelys Knitro, requires Artelys Knitro solver https://www.artelys.com/solvers/knitro/ 'MIPS' : (LP, QP, NLP) MIPS, MATPOWER Interior Point Solver pure MATLAB implementation of a primal-dual interior point method, if mips_opt.step_control = 1 it uses MIPS-sc, a step controlled variant of MIPS 'MOSEK' : (LP, QP, MILP, MIQP) MOSEK 'NEWTON' : (NLEQ) Newton's method 'OSQP' : (LP, QP) OSQP, https://osqp.org 'OT' : (LP, QP, MILP) MATLAB Optimization Toolbox, LINPROG, QUADPROG or INTLINPROG verbose (0) - controls level of progress output displayed 0 = no progress output 1 = some progress output 2 = verbose progress output bp_opt - options vector for BP (BPMPD) clp_opt - options vector for CLP cplex_opt - options struct for CPLEX fd_opt - options struct for fast-decoupled Newton's method, nleqs_fd_newton() fmincon_opt - options struct for FMINCON fsolve_opt - options struct for FSOLVE glpk_opt - options struct for GLPK grb_opt - options struct for GUROBI gs_opt - options struct for Gauss-Seidel method, nleqs_gauss_seidel() intlinprog_opt - options struct for INTLINPROG ipopt_opt - options struct for IPOPT knitro_opt - options struct for Artelys Knitro leq_opt - options struct for MPLINSOLVE, with 'solver' and 'opt' fields corresponding to respective MPLINSOLVE args linprog_opt - options struct for LINPROG mips_opt - options struct for MIPS mosek_opt - options struct for MOSEK newton_opt - options struct for Newton method, NLEQS_NEWTON osqp_opt - options struct for OSQP quadprog_opt - options struct for QUADPROG parse_soln (0) - flag that specifies whether or not to call the PARSE_SOLN method and place the return values in OM.soln. price_stage_warn_tol (1e-7) - tolerance on the objective fcn value and primal variable relative match required to avoid mis-match warning message if mixed integer price computation stage is not skipped skip_prices (0) - flag that specifies whether or not to skip the price computation stage for mixed integer problems, in which the problem is re-solved for only the continuous variables, with all others being constrained to their solved values x0 (empty) - optional initial value of x, overrides value stored in model (ignored by some solvers) Outputs: X : solution vector F : final (objective) function value EXITFLAG : exit flag 1 = converged 0 or negative values = solver specific failure codes OUTPUT : output struct with the following fields: alg - algorithm code of solver used (others) - solver specific fields JAC : final Jacobian matrix (if available, for LEQ/NLEQ problems) LAMBDA : (for all non-NLEQ problem types) struct containing the Langrange and Kuhn-Tucker multipliers on the constraints, with fields: eqnonlin - nonlinear equality constraints ineqnonlin - nonlinear inequality constraints 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 See also OPT_MODEL, QPS_MASTER, MIQPS_MASTER, NLPS_MASTER
0001 function [x, f, eflag, output, lambda] = solve(om, opt) 0002 %SOLVE Solve the optimization model. 0003 % X = OM.SOLVE() 0004 % [X, F] = OM.SOLVE() 0005 % [X, F, EXITFLAG] = OM.SOLVE() 0006 % [X, F, EXITFLAG, OUTPUT] = OM.SOLVE() 0007 % [X, F, EXITFLAG, OUTPUT, JAC] = OM.SOLVE() (NLEQ problems) 0008 % [X, F, EXITFLAG, OUTPUT, LAMBDA] = OM.SOLVE() (other problem types) 0009 % [X ...] = OM.SOLVE(OPT) 0010 % 0011 % Solves the optimization model using one of the following, depending 0012 % on the problem type: QPS_MASTER, MIQPS_MASTER, NLPS_MASTER, NLEQS_MASTER. 0013 % 0014 % Inputs: 0015 % OPT : optional options structure with the following fields, 0016 % all of which are also optional (default values shown in 0017 % parentheses) 0018 % alg ('DEFAULT') : determines which solver to use, list of relevant 0019 % problem types are listed in parens next to each 0020 % 'DEFAULT' : automatic, depending on problem type, uses the 0021 % the first available of: 0022 % LP - Gurobi, CPLEX, MOSEK, linprog (if MATLAB), GLPK, 0023 % BPMPD, MIPS 0024 % QP - Gurobi, CPLEX, MOSEK, quadprog (if MATLAB), BPMPD, 0025 % MIPS 0026 % MILP - Gurobi, CPLEX, MOSEK, Opt Tbx (intlingprog), GLPK 0027 % MIQP - Gurobi, CPLEX, MOSEK 0028 % NLP - MIPS 0029 % MINLP - Artelys Knitro (not yet implemented) 0030 % NLEQ - Newton's method 0031 % 'BPMPD' : (LP, QP) BPMPD_MEX 0032 % 'CLP' : (LP, QP) CLP 0033 % 'CPLEX' : (LP, QP, MILP, MIQP) CPLEX 0034 % 'FD' : (NLEQ) fast-decoupled Newon's method 0035 % 'FMINCON' : (NLP) FMINCON, MATLAB Optimization Toolbox 0036 % 'FSOLVE' : (NLEQ) FSOLVE, MATLAB Optimization Toolbox 0037 % 'GLPK' : (LP, MILP) GLPK 0038 % 'GS' : (NLEQ) Gauss-Seidel 0039 % 'GUROBI' : (LP, QP, MILP, MIQP) Gurobi 0040 % 'IPOPT' : (LP, QP, NLP) IPOPT, requires MEX interface to IPOPT solver 0041 % https://github.com/coin-or/Ipopt 0042 % 'KNITRO' : (NLP, MINLP) Artelys Knitro, requires Artelys Knitro solver 0043 % https://www.artelys.com/solvers/knitro/ 0044 % 'MIPS' : (LP, QP, NLP) MIPS, MATPOWER Interior Point Solver 0045 % pure MATLAB implementation of a primal-dual 0046 % interior point method, if mips_opt.step_control = 1 0047 % it uses MIPS-sc, a step controlled variant of MIPS 0048 % 'MOSEK' : (LP, QP, MILP, MIQP) MOSEK 0049 % 'NEWTON' : (NLEQ) Newton's method 0050 % 'OSQP' : (LP, QP) OSQP, https://osqp.org 0051 % 'OT' : (LP, QP, MILP) MATLAB Optimization Toolbox, 0052 % LINPROG, QUADPROG or INTLINPROG 0053 % verbose (0) - controls level of progress output displayed 0054 % 0 = no progress output 0055 % 1 = some progress output 0056 % 2 = verbose progress output 0057 % bp_opt - options vector for BP (BPMPD) 0058 % clp_opt - options vector for CLP 0059 % cplex_opt - options struct for CPLEX 0060 % fd_opt - options struct for fast-decoupled Newton's method, 0061 % nleqs_fd_newton() 0062 % fmincon_opt - options struct for FMINCON 0063 % fsolve_opt - options struct for FSOLVE 0064 % glpk_opt - options struct for GLPK 0065 % grb_opt - options struct for GUROBI 0066 % gs_opt - options struct for Gauss-Seidel method, 0067 % nleqs_gauss_seidel() 0068 % intlinprog_opt - options struct for INTLINPROG 0069 % ipopt_opt - options struct for IPOPT 0070 % knitro_opt - options struct for Artelys Knitro 0071 % leq_opt - options struct for MPLINSOLVE, with 'solver' and 0072 % 'opt' fields corresponding to respective MPLINSOLVE args 0073 % linprog_opt - options struct for LINPROG 0074 % mips_opt - options struct for MIPS 0075 % mosek_opt - options struct for MOSEK 0076 % newton_opt - options struct for Newton method, NLEQS_NEWTON 0077 % osqp_opt - options struct for OSQP 0078 % quadprog_opt - options struct for QUADPROG 0079 % parse_soln (0) - flag that specifies whether or not to call 0080 % the PARSE_SOLN method and place the return values in OM.soln. 0081 % price_stage_warn_tol (1e-7) - tolerance on the objective fcn 0082 % value and primal variable relative match required to avoid 0083 % mis-match warning message if mixed integer price computation 0084 % stage is not skipped 0085 % skip_prices (0) - flag that specifies whether or not to skip the 0086 % price computation stage for mixed integer problems, in which 0087 % the problem is re-solved for only the continuous variables, 0088 % with all others being constrained to their solved values 0089 % x0 (empty) - optional initial value of x, overrides value 0090 % stored in model (ignored by some solvers) 0091 % 0092 % Outputs: 0093 % X : solution vector 0094 % F : final (objective) function value 0095 % EXITFLAG : exit flag 0096 % 1 = converged 0097 % 0 or negative values = solver specific failure codes 0098 % OUTPUT : output struct with the following fields: 0099 % alg - algorithm code of solver used 0100 % (others) - solver specific fields 0101 % JAC : final Jacobian matrix (if available, for LEQ/NLEQ problems) 0102 % LAMBDA : (for all non-NLEQ problem types) struct containing the 0103 % Langrange and Kuhn-Tucker multipliers on the constraints, with 0104 % fields: 0105 % eqnonlin - nonlinear equality constraints 0106 % ineqnonlin - nonlinear inequality constraints 0107 % mu_l - lower (left-hand) limit on linear constraints 0108 % mu_u - upper (right-hand) limit on linear constraints 0109 % lower - lower bound on optimization variables 0110 % upper - upper bound on optimization variables 0111 % 0112 % See also OPT_MODEL, QPS_MASTER, MIQPS_MASTER, NLPS_MASTER 0113 0114 % MP-Opt-Model 0115 % Copyright (c) 2020, Power Systems Engineering Research Center (PSERC) 0116 % by Ray Zimmerman, PSERC Cornell 0117 % 0118 % This file is part of MP-Opt-Model. 0119 % Covered by the 3-clause BSD License (see LICENSE file for details). 0120 % See https://github.com/MATPOWER/mp-opt-model for more info. 0121 0122 if nargin < 2 0123 opt = struct(); 0124 end 0125 % opt.parse_soln = 1; 0126 0127 %% call appropriate solver 0128 pt = om.problem_type(); 0129 switch pt 0130 case 'MINLP' %% MINLP - mixed integer non-linear program 0131 error('@opt_model/solve: not yet implemented for ''MINLP'' problems.') 0132 case 'LEQ' %% LEQ - linear equations 0133 if isfield(opt, 'leq_opt') && isfield(opt.leq_opt, 'solver') 0134 leq_solver = opt.leq_opt.solver; 0135 else 0136 leq_solver = ''; 0137 end 0138 if isfield(opt, 'leq_opt') && isfield(opt.leq_opt, 'opt') 0139 leq_opt = opt.leq_opt.opt; 0140 else 0141 leq_opt = struct(); 0142 end 0143 [A, b] = om.params_lin_constraint(); 0144 x = mplinsolve(A, b, leq_solver, leq_opt); 0145 f = A*x - b; 0146 eflag = 1; 0147 output = struct('alg', leq_solver); 0148 lambda = A; %% jac 0149 case 'NLEQ' %% NLEQ - nonlinear equations 0150 x0 = om.params_var(); 0151 if isfield(opt, 'x0') 0152 x0 = opt.x0; 0153 end 0154 0155 if om.getN('lin') 0156 [A, b] = om.params_lin_constraint(); 0157 fcn = @(x)nleq_fcn_(om, x, A, b); 0158 else 0159 fcn = @(x)om.eval_nln_constraint(x, 1); 0160 end 0161 [x, f, eflag, output, lambda] = nleqs_master(fcn, x0, opt); 0162 case 'NLP' %% NLP - nonlinear program 0163 %% optimization vars, bounds, types 0164 [x0, xmin, xmax] = om.params_var(); 0165 if isfield(opt, 'x0') 0166 x0 = opt.x0; 0167 end 0168 0169 %% run solver 0170 [A, l, u] = om.params_lin_constraint(); 0171 f_fcn = @(x)nlp_costfcn(om, x); 0172 gh_fcn = @(x)nlp_consfcn(om, x); 0173 hess_fcn = @(x, lambda, cost_mult)nlp_hessfcn(om, x, lambda, cost_mult); 0174 [x, f, eflag, output, lambda] = ... 0175 nlps_master(f_fcn, x0, A, l, u, xmin, xmax, gh_fcn, hess_fcn, opt); 0176 otherwise 0177 %% get parameters 0178 [HH, CC, C0] = om.params_quad_cost(); 0179 [A, l, u] = om.params_lin_constraint(); 0180 0181 if strcmp(pt(1:2), 'MI') %% MILP, MIQP - mixed integer linear/quadratic program 0182 %% optimization vars, bounds, types 0183 [x0, xmin, xmax, vtype] = om.params_var(); 0184 if isfield(opt, 'x0') 0185 x0 = opt.x0; 0186 end 0187 0188 %% run solver 0189 [x, f, eflag, output, lambda] = ... 0190 miqps_master(HH, CC, A, l, u, xmin, xmax, x0, vtype, opt); 0191 else %% LP, QP - linear/quadratic program 0192 %% optimization vars, bounds, types 0193 [x0, xmin, xmax] = om.params_var(); 0194 if isfield(opt, 'x0') 0195 x0 = opt.x0; 0196 end 0197 0198 %% run solver 0199 [x, f, eflag, output, lambda] = ... 0200 qps_master(HH, CC, A, l, u, xmin, xmax, x0, opt); 0201 end 0202 f = f + C0; 0203 end 0204 0205 %% store solution 0206 om.soln.eflag = eflag; 0207 om.soln.x = x; 0208 om.soln.f = f; 0209 om.soln.output = output; 0210 if isstruct(lambda) 0211 om.soln.lambda = lambda; 0212 else 0213 om.soln.jac = lambda; 0214 end 0215 0216 %% parse solution 0217 if isfield(opt, 'parse_soln') && opt.parse_soln 0218 ps = om.parse_soln(); 0219 om.soln = nested_struct_copy(om.soln, ps, struct('copy_mode', '=')); 0220 end 0221 0222 %% system of nonlinear and linear equations 0223 function [f, J] = nleq_fcn_(om, x, A, b) 0224 if nargout > 1 0225 [ff, JJ] = om.eval_nln_constraint(x, 1); 0226 J = [JJ; A]; 0227 else 0228 ff = om.eval_nln_constraint(x, 1); 0229 end 0230 f = [ff; A*x - b];