ADD_CONSTRAINTS Adds a set of constraints to the model. OM = ADD_CONSTRAINTS(OM, NAME, A, L, U); OM = ADD_CONSTRAINTS(OM, NAME, A, L, U, VARSETS); OM = ADD_CONSTRAINTS(OM, NAME, DIM_LIST); OM = ADD_CONSTRAINTS(OM, NAME, IDX_LIST, A, L, U); OM = ADD_CONSTRAINTS(OM, NAME, IDX_LIST, A, L, U, VARSETS); OM = ADD_CONSTRAINTS(OM, NAME, N, 'NON-LINEAR'); Linear constraints are of the form L <= A * x <= U, where x is a vector made of of the vars specified in VARSETS (in the order given). This allows the A matrix to be defined only in terms of the relevant variables without the need to manually create a lot of zero columns. If VARSETS is empty, x is taken to be the full vector of all optimization variables. If L or U are empty, they are assumed to be appropriately sized vectors of -Inf and Inf, respectively. For nonlinear constraints, the 3rd argument, N, is the number of constraints in the set. Currently, this is used internally by MATPOWER, but there is no way for the user to specify additional nonlinear constraints. Examples: om = add_constraints(om, 'vl', Avl, lvl, uvl, {'Pg', 'Qg'}); om = add_constraints(om, 'Pmis', nb, 'nonlinear'); om = add_constraints(om, 'R', {2, 3}); for i = 1:2 for j = 1:3 om = add_constraints(om, 'R', {i, j}, A{i,j}, ...); end end See also OPT_MODEL, LINEAR_CONSTRAINTS.
0001 function om = add_constraints(om, name, idx, varargin) 0002 %ADD_CONSTRAINTS Adds a set of constraints to the model. 0003 % OM = ADD_CONSTRAINTS(OM, NAME, A, L, U); 0004 % OM = ADD_CONSTRAINTS(OM, NAME, A, L, U, VARSETS); 0005 % OM = ADD_CONSTRAINTS(OM, NAME, DIM_LIST); 0006 % OM = ADD_CONSTRAINTS(OM, NAME, IDX_LIST, A, L, U); 0007 % OM = ADD_CONSTRAINTS(OM, NAME, IDX_LIST, A, L, U, VARSETS); 0008 % OM = ADD_CONSTRAINTS(OM, NAME, N, 'NON-LINEAR'); 0009 % 0010 % Linear constraints are of the form L <= A * x <= U, where 0011 % x is a vector made of of the vars specified in VARSETS (in 0012 % the order given). This allows the A matrix to be defined only 0013 % in terms of the relevant variables without the need to manually 0014 % create a lot of zero columns. If VARSETS is empty, x is taken 0015 % to be the full vector of all optimization variables. If L or 0016 % U are empty, they are assumed to be appropriately sized vectors 0017 % of -Inf and Inf, respectively. 0018 % 0019 % For nonlinear constraints, the 3rd argument, N, is the number 0020 % of constraints in the set. Currently, this is used internally 0021 % by MATPOWER, but there is no way for the user to specify 0022 % additional nonlinear constraints. 0023 % 0024 % Examples: 0025 % om = add_constraints(om, 'vl', Avl, lvl, uvl, {'Pg', 'Qg'}); 0026 % om = add_constraints(om, 'Pmis', nb, 'nonlinear'); 0027 % 0028 % om = add_constraints(om, 'R', {2, 3}); 0029 % for i = 1:2 0030 % for j = 1:3 0031 % om = add_constraints(om, 'R', {i, j}, A{i,j}, ...); 0032 % end 0033 % end 0034 % 0035 % See also OPT_MODEL, LINEAR_CONSTRAINTS. 0036 0037 % MATPOWER 0038 % $Id: add_constraints.m 2137 2013-03-29 18:52:50Z ray $ 0039 % by Ray Zimmerman, PSERC Cornell 0040 % Copyright (c) 2008-2012 by Power System Engineering Research Center (PSERC) 0041 % 0042 % This file is part of MATPOWER. 0043 % See http://www.pserc.cornell.edu/matpower/ for more info. 0044 % 0045 % MATPOWER is free software: you can redistribute it and/or modify 0046 % it under the terms of the GNU General Public License as published 0047 % by the Free Software Foundation, either version 3 of the License, 0048 % or (at your option) any later version. 0049 % 0050 % MATPOWER is distributed in the hope that it will be useful, 0051 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0052 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0053 % GNU General Public License for more details. 0054 % 0055 % You should have received a copy of the GNU General Public License 0056 % along with MATPOWER. If not, see <http://www.gnu.org/licenses/>. 0057 % 0058 % Additional permission under GNU GPL version 3 section 7 0059 % 0060 % If you modify MATPOWER, or any covered work, to interface with 0061 % other modules (such as MATLAB code and MEX-files) available in a 0062 % MATLAB(R) or comparable environment containing parts covered 0063 % under other licensing terms, the licensors of MATPOWER grant 0064 % you additional permission to convey the resulting work. 0065 0066 nonlin = 0; 0067 if iscell(idx) 0068 if length(varargin) %% linear: indexed named set 0069 s1 = substruct('.', name, '()', idx); 0070 s2 = substruct('.', name, '{}', idx); 0071 0072 %% prevent duplicate named constraint sets 0073 if subsref(om.lin.idx.i1, s1) ~= 0 0074 str = '%d'; for m = 2:length(idx), str = [str ',%d']; end 0075 nname = sprintf(['%s(' str, ')'], name, idx{:}); 0076 error('@opt_model/add_constraints: linear constraint set named ''%s'' already exists', nname); 0077 end 0078 0079 A = varargin{1}; 0080 args = { varargin{2:end} }; 0081 else %% linear: just setting dimensions for indexed set 0082 %% prevent duplicate named constraint sets 0083 if isfield(om.lin.idx.N, name) 0084 error('@opt_model/add_constraints: linear constraint set named ''%s'' already exists', name); 0085 end 0086 0087 A = sparse(0,0); 0088 args = {}; 0089 end 0090 else 0091 if length(varargin) == 1 %% non-linear 0092 %% prevent duplicate named constraint sets 0093 if isfield(om.nln.idx.N, name) 0094 error('@opt_model/add_constraints: nonlinear constraint set named ''%s'' already exists', name); 0095 end 0096 0097 nonlin = 1; 0098 N = idx; 0099 args = {}; 0100 else %% linear: simple named set 0101 %% prevent duplicate named constraint sets 0102 if isfield(om.lin.idx.N, name) 0103 error('@opt_model/add_constraints: linear constraint set named ''%s'' already exists', name); 0104 end 0105 0106 A = idx; 0107 args = varargin; 0108 end 0109 idx = {}; 0110 end 0111 nargs = length(args); 0112 0113 if nonlin %% nonlinear 0114 %% add info about this nonlinear constraint set 0115 om.nln.idx.i1.(name) = om.nln.N + 1; %% starting index 0116 om.nln.idx.iN.(name) = om.nln.N + N; %% ending index 0117 om.nln.idx.N.(name) = N; %% number of constraints 0118 0119 %% update number of nonlinear constraints and constraint sets 0120 om.nln.N = om.nln.idx.iN.(name); 0121 om.nln.NS = om.nln.NS + 1; 0122 0123 %% add to ordered list of nonlinear constraint sets 0124 om.nln.order(om.nln.NS).name = name; 0125 om.nln.order(om.nln.NS).idx = {}; 0126 elseif nargs == 0 %% linear: just setting dimensions for indexed set 0127 %% add info about this linear constraint set 0128 om.lin.idx.i1.(name) = zeros(idx{:}); %% starting index 0129 om.lin.idx.iN.(name) = zeros(idx{:}); %% ending index 0130 om.lin.idx.N.(name) = zeros(idx{:}); %% number of constraints 0131 om.lin.data.A.(name) = cell(idx{:}); 0132 om.lin.data.l.(name) = cell(idx{:}); 0133 om.lin.data.u.(name) = cell(idx{:}); 0134 om.lin.data.vs.(name) = cell(idx{:}); 0135 else %% linear 0136 if nargs >= 3 0137 [l, u, varsets] = deal(args{1:3}); 0138 else 0139 varsets = {}; 0140 if nargs >= 2 0141 [l, u] = deal(args{1:2}); 0142 else 0143 u = []; 0144 if nargs >= 1 0145 l = args{1}; 0146 else 0147 l = []; 0148 end 0149 end 0150 end 0151 0152 [N, M] = size(A); 0153 if isempty(l) %% default l is -Inf 0154 l = -Inf * ones(N, 1); 0155 end 0156 if isempty(u) %% default u is Inf 0157 u = Inf * ones(N, 1); 0158 end 0159 if ~isempty(varsets) && iscell(varsets) 0160 empty_cells = cell(1, length(varsets)); 0161 [empty_cells{:}] = deal({}); %% empty cell arrays 0162 varsets = struct('name', varsets, 'idx', empty_cells); 0163 end 0164 0165 %% check sizes 0166 if size(l, 1) ~= N || size(u, 1) ~= N 0167 error('@opt_model/add_constraints: sizes of A, l and u must match'); 0168 end 0169 if isempty(varsets) 0170 nv = om.var.N; 0171 else 0172 nv = 0; 0173 for k = 1:length(varsets) 0174 s = substruct('.', varsets(k).name, '()', varsets(k).idx); 0175 nv = nv + subsref(om.var.idx.N, s); 0176 end 0177 end 0178 if M ~= nv 0179 error('@opt_model/add_constraints: number of columns of A does not match\nnumber of variables, A is %d x %d, nv = %d\n', N, M, nv); 0180 end 0181 if isempty(idx) %% linear: simple named set 0182 %% add info about this linear constraint set 0183 om.lin.idx.i1.(name) = om.lin.N + 1; %% starting index 0184 om.lin.idx.iN.(name) = om.lin.N + N; %% ending index 0185 om.lin.idx.N.(name) = N; %% number of constraints 0186 om.lin.data.A.(name) = A; 0187 om.lin.data.l.(name) = l; 0188 om.lin.data.u.(name) = u; 0189 om.lin.data.vs.(name) = varsets; 0190 0191 %% update number of linear constraints and constraint sets 0192 om.lin.N = om.lin.idx.iN.(name); 0193 om.lin.NS = om.lin.NS + 1; 0194 0195 %% add to ordered list of linear constraint sets 0196 om.lin.order(om.lin.NS).name = name; 0197 om.lin.order(om.lin.NS).idx = {}; 0198 else %% linear: indexed named set 0199 %% add info about this linear constraint set 0200 om.lin.idx.i1 = subsasgn(om.lin.idx.i1, s1, om.lin.N + 1); %% starting index 0201 om.lin.idx.iN = subsasgn(om.lin.idx.iN, s1, om.lin.N + N); %% ending index 0202 om.lin.idx.N = subsasgn(om.lin.idx.N, s1, N); %% number of constraints 0203 om.lin.data.A = subsasgn(om.lin.data.A, s2, A); 0204 om.lin.data.l = subsasgn(om.lin.data.l, s2, l); 0205 om.lin.data.u = subsasgn(om.lin.data.u, s2, u); 0206 om.lin.data.vs = subsasgn(om.lin.data.vs, s2, varsets); 0207 0208 %% update number of linear constraints and constraint sets 0209 om.lin.N = subsref(om.lin.idx.iN, s1); 0210 om.lin.NS = om.lin.NS + 1; 0211 0212 %% add to ordered list of linear constraint sets 0213 om.lin.order(om.lin.NS).name = name; 0214 om.lin.order(om.lin.NS).idx = idx; 0215 end 0216 end