ADD_COSTS Adds a set of user costs to the model. OM = ADD_COSTS(OM, NAME, CP); OM = ADD_COSTS(OM, NAME, CP, VARSETS); OM = ADD_COSTS(OM, NAME, DIM_LIST); OM = ADD_COSTS(OM, NAME, IDX_LIST, CP); OM = ADD_COSTS(OM, NAME, IDX_LIST, CP, VARSETS); Adds a named block of user-defined costs to the model. Each set is defined by the CP struct described below. All user-defined sets of costs are combined together into a single set of cost parameters in a single CP struct by BULD_COST_PARAMS. This full aggregate set of cost parameters can be retreived from the model by GET_COST_PARAMS. Examples: cp1 = struct('N', N1, 'Cw', Cw1); cp2 = struct('N', N2, 'Cw', Cw2, 'H', H, 'dd', dd, ... 'rh', rh, 'kk', kk, 'mm', mm); om = add_costs(om, 'usr1', cp1, {'Pg', 'Qg', 'z'}); om = add_costs(om, 'usr2', cp2, {'Vm', 'Pg', 'Qg', 'z'}); om = add_costs(om, 'c', {2, 3}); for i = 1:2 for j = 1:3 om = add_costs(om, 'c', {i, j}, cp(i,j), ...); end end Let x refer to the vector formed by combining the specified VARSETS, and f_u(x, CP) be the cost at x corresponding to the cost parameters contained in CP, where CP is a struct with the following fields: N - nw x nx sparse matrix (optional, identity matrix by default) Cw - nw x 1 vector H - nw x nw sparse matrix (optional, all zeros by default) dd, mm - nw x 1 vectors (optional, all ones by default) rh, kk - nw x 1 vectors (optional, all zeros by default) These parameters are used as follows to compute f_u(x, CP) R = N*x - rh / kk(i), R(i) < -kk(i) K(i) = < 0, -kk(i) <= R(i) <= kk(i) \ -kk(i), R(i) > kk(i) RR = R + K U(i) = / 0, -kk(i) <= R(i) <= kk(i) \ 1, otherwise DDL(i) = / 1, dd(i) = 1 \ 0, otherwise DDQ(i) = / 1, dd(i) = 2 \ 0, otherwise Dl = diag(mm) * diag(U) * diag(DDL) Dq = diag(mm) * diag(U) * diag(DDQ) w = (Dl + Dq * diag(RR)) * RR f_u(x, CP) = 1/2 * w'*H*w + Cw'*w See also OPT_MODEL, BUILD_COST_PARAMS, GET_COST_PARAMS, COMPUTE_COST.
0001 function om = add_costs(om, name, idx, varargin) 0002 %ADD_COSTS Adds a set of user costs to the model. 0003 % OM = ADD_COSTS(OM, NAME, CP); 0004 % OM = ADD_COSTS(OM, NAME, CP, VARSETS); 0005 % OM = ADD_COSTS(OM, NAME, DIM_LIST); 0006 % OM = ADD_COSTS(OM, NAME, IDX_LIST, CP); 0007 % OM = ADD_COSTS(OM, NAME, IDX_LIST, CP, VARSETS); 0008 % 0009 % Adds a named block of user-defined costs to the model. Each set is 0010 % defined by the CP struct described below. All user-defined sets of 0011 % costs are combined together into a single set of cost parameters in 0012 % a single CP struct by BULD_COST_PARAMS. This full aggregate set of 0013 % cost parameters can be retreived from the model by GET_COST_PARAMS. 0014 % 0015 % Examples: 0016 % cp1 = struct('N', N1, 'Cw', Cw1); 0017 % cp2 = struct('N', N2, 'Cw', Cw2, 'H', H, 'dd', dd, ... 0018 % 'rh', rh, 'kk', kk, 'mm', mm); 0019 % om = add_costs(om, 'usr1', cp1, {'Pg', 'Qg', 'z'}); 0020 % om = add_costs(om, 'usr2', cp2, {'Vm', 'Pg', 'Qg', 'z'}); 0021 % 0022 % om = add_costs(om, 'c', {2, 3}); 0023 % for i = 1:2 0024 % for j = 1:3 0025 % om = add_costs(om, 'c', {i, j}, cp(i,j), ...); 0026 % end 0027 % end 0028 % 0029 % Let x refer to the vector formed by combining the specified VARSETS, 0030 % and f_u(x, CP) be the cost at x corresponding to the cost parameters 0031 % contained in CP, where CP is a struct with the following fields: 0032 % N - nw x nx sparse matrix (optional, identity matrix by default) 0033 % Cw - nw x 1 vector 0034 % H - nw x nw sparse matrix (optional, all zeros by default) 0035 % dd, mm - nw x 1 vectors (optional, all ones by default) 0036 % rh, kk - nw x 1 vectors (optional, all zeros by default) 0037 % 0038 % These parameters are used as follows to compute f_u(x, CP) 0039 % 0040 % R = N*x - rh 0041 % 0042 % / kk(i), R(i) < -kk(i) 0043 % K(i) = < 0, -kk(i) <= R(i) <= kk(i) 0044 % \ -kk(i), R(i) > kk(i) 0045 % 0046 % RR = R + K 0047 % 0048 % U(i) = / 0, -kk(i) <= R(i) <= kk(i) 0049 % \ 1, otherwise 0050 % 0051 % DDL(i) = / 1, dd(i) = 1 0052 % \ 0, otherwise 0053 % 0054 % DDQ(i) = / 1, dd(i) = 2 0055 % \ 0, otherwise 0056 % 0057 % Dl = diag(mm) * diag(U) * diag(DDL) 0058 % Dq = diag(mm) * diag(U) * diag(DDQ) 0059 % 0060 % w = (Dl + Dq * diag(RR)) * RR 0061 % 0062 % f_u(x, CP) = 1/2 * w'*H*w + Cw'*w 0063 % 0064 % See also OPT_MODEL, BUILD_COST_PARAMS, GET_COST_PARAMS, COMPUTE_COST. 0065 0066 % MATPOWER 0067 % $Id: add_costs.m 2209 2013-10-14 16:34:55Z ray $ 0068 % by Ray Zimmerman, PSERC Cornell 0069 % Copyright (c) 2008-2012 by Power System Engineering Research Center (PSERC) 0070 % 0071 % This file is part of MATPOWER. 0072 % See http://www.pserc.cornell.edu/matpower/ for more info. 0073 % 0074 % MATPOWER is free software: you can redistribute it and/or modify 0075 % it under the terms of the GNU General Public License as published 0076 % by the Free Software Foundation, either version 3 of the License, 0077 % or (at your option) any later version. 0078 % 0079 % MATPOWER is distributed in the hope that it will be useful, 0080 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0081 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0082 % GNU General Public License for more details. 0083 % 0084 % You should have received a copy of the GNU General Public License 0085 % along with MATPOWER. If not, see <http://www.gnu.org/licenses/>. 0086 % 0087 % Additional permission under GNU GPL version 3 section 7 0088 % 0089 % If you modify MATPOWER, or any covered work, to interface with 0090 % other modules (such as MATLAB code and MEX-files) available in a 0091 % MATLAB(R) or comparable environment containing parts covered 0092 % under other licensing terms, the licensors of MATPOWER grant 0093 % you additional permission to convey the resulting work. 0094 0095 if iscell(idx) 0096 if length(varargin) %% indexed named set 0097 s1 = substruct('.', name, '()', idx); 0098 s2 = substruct('.', name, '{}', idx); 0099 0100 %% prevent duplicate named cost sets 0101 if subsref(om.cost.idx.i1, s1) ~= 0 0102 str = '%d'; for m = 2:length(idx), str = [str ',%d']; end 0103 nname = sprintf(['%s(' str, ')'], name, idx{:}); 0104 error('@opt_model/add_costs: cost set named ''%s'' already exists', nname); 0105 end 0106 0107 cp = varargin{1}; 0108 args = { varargin{2:end} }; 0109 else %% just setting dimensions for indexed set 0110 %% prevent duplicate named cost sets 0111 if isfield(om.cost.idx.N, name) 0112 error('@opt_model/add_costs: cost set named ''%s'' already exists', name); 0113 end 0114 0115 cp = []; 0116 args = {}; 0117 end 0118 else %% simple named set 0119 %% prevent duplicate named cost sets 0120 if isfield(om.cost.idx.N, name) 0121 error('@opt_model/add_costs: cost set named ''%s'' already exists', name); 0122 end 0123 0124 cp = idx; 0125 args = varargin; 0126 idx = {}; 0127 end 0128 0129 if isempty(cp) %% just setting dimensions for indexed set 0130 %% add info about this cost set 0131 om.cost.idx.i1.(name) = zeros(idx{:}); %% starting index 0132 om.cost.idx.iN.(name) = zeros(idx{:}); %% ending index 0133 om.cost.idx.N.(name) = zeros(idx{:}); %% number of costs (nw) 0134 om.cost.data.N.(name) = cell(idx{:}); 0135 om.cost.data.Cw.(name) = cell(idx{:}); 0136 om.cost.data.vs.(name) = cell(idx{:}); 0137 else 0138 if isempty(args) 0139 varsets = {}; 0140 else 0141 varsets = args{1}; 0142 end 0143 if ~isempty(varsets) && iscell(varsets) 0144 empty_cells = cell(1, length(varsets)); 0145 [empty_cells{:}] = deal({}); %% empty cell arrays 0146 varsets = struct('name', varsets, 'idx', empty_cells); 0147 end 0148 if isfield(cp, 'N') 0149 [nw, nx] = size(cp.N); 0150 else 0151 nw = length(cp.Cw); 0152 nx = nw; 0153 cp.N = speye(nw, nx); 0154 end 0155 0156 %% check sizes 0157 if isempty(varsets) 0158 nv = om.var.N; 0159 else 0160 nv = 0; 0161 for k = 1:length(varsets) 0162 s = substruct('.', varsets(k).name, '()', varsets(k).idx); 0163 nv = nv + subsref(om.var.idx.N, s); 0164 end 0165 end 0166 if nx ~= nv 0167 if nw == 0 0168 cp.N = sparse(nw, nx); 0169 else 0170 error('@opt_model/add_costs: number of columns in N (%d x %d) does not match\nnumber of variables (%d)\n', nw, nx, nv); 0171 end 0172 end 0173 if size(cp.Cw, 1) ~= nw 0174 error('@opt_model/add_costs: number of rows of Cw (%d x %d) and N (%d x %d) must match\n', size(cp.Cw), nw, nx); 0175 end 0176 if isfield(cp, 'H') && (size(cp.H, 1) ~= nw || size(cp.H, 2) ~= nw) 0177 error('@opt_model/add_costs: both dimensions of H (%d x %d) must match the number of rows in N (%d x %d)\n', size(cp.H), nw, nx); 0178 end 0179 if isfield(cp, 'dd') && size(cp.dd, 1) ~= nw 0180 error('@opt_model/add_costs: number of rows of dd (%d x %d) and N (%d x %d) must match\n', size(cp.dd), nw, nx); 0181 end 0182 if isfield(cp, 'rh') && size(cp.rh, 1) ~= nw 0183 error('@opt_model/add_costs: number of rows of rh (%d x %d) and N (%d x %d) must match\n', size(cp.rh), nw, nx); 0184 end 0185 if isfield(cp, 'kk') && size(cp.kk, 1) ~= nw 0186 error('@opt_model/add_costs: number of rows of kk (%d x %d) and N (%d x %d) must match\n', size(cp.kk), nw, nx); 0187 end 0188 if isfield(cp, 'mm') && size(cp.mm, 1) ~= nw 0189 error('@opt_model/add_costs: number of rows of mm (%d x %d) and N (%d x %d) must match\n', size(cp.mm), nw, nx); 0190 end 0191 0192 if isempty(idx) %% simple named set 0193 %% add info about this user cost set 0194 om.cost.idx.i1.(name) = om.cost.N + 1; %% starting index 0195 om.cost.idx.iN.(name) = om.cost.N + nw; %% ending index 0196 om.cost.idx.N.(name) = nw; %% number of costs (nw) 0197 om.cost.data.N.(name) = cp.N; 0198 om.cost.data.Cw.(name) = cp.Cw; 0199 om.cost.data.vs.(name) = varsets; 0200 if isfield(cp, 'H') 0201 om.cost.data.H.(name) = cp.H; 0202 end 0203 if isfield(cp, 'dd') 0204 om.cost.data.dd.(name) = cp.dd; 0205 end 0206 if isfield(cp, 'rh') 0207 om.cost.data.rh.(name) = cp.rh; 0208 end 0209 if isfield(cp, 'kk') 0210 om.cost.data.kk.(name) = cp.kk; 0211 end 0212 if isfield(cp, 'mm') 0213 om.cost.data.mm.(name) = cp.mm; 0214 end 0215 0216 %% update number of vars and var sets 0217 om.cost.N = om.cost.idx.iN.(name); 0218 om.cost.NS = om.cost.NS + 1; 0219 0220 %% add to ordered list of var sets 0221 om.cost.order(om.cost.NS).name = name; 0222 om.cost.order(om.cost.NS).idx = {}; 0223 else %% indexed named set 0224 %% add info about this user cost set 0225 om.cost.idx.i1 = subsasgn(om.cost.idx.i1, s1, om.cost.N + 1); %% starting index 0226 om.cost.idx.iN = subsasgn(om.cost.idx.iN, s1, om.cost.N + nw); %% ending index 0227 om.cost.idx.N = subsasgn(om.cost.idx.N, s1, nw); %% number of costs (nw) 0228 0229 om.cost.data.N = subsasgn(om.cost.data.N, s2, cp.N); 0230 om.cost.data.Cw = subsasgn(om.cost.data.Cw, s2, cp.Cw); 0231 om.cost.data.vs = subsasgn(om.cost.data.vs, s2, varsets); 0232 if isfield(cp, 'H') 0233 om.cost.data.H = subsasgn(om.cost.data.H, s2, cp.H); 0234 end 0235 if isfield(cp, 'dd') 0236 om.cost.data.dd = subsasgn(om.cost.data.dd, s2, cp.dd); 0237 end 0238 if isfield(cp, 'rh') 0239 om.cost.data.rh = subsasgn(om.cost.data.rh, s2, cp.rh); 0240 end 0241 if isfield(cp, 'kk') 0242 om.cost.data.kk = subsasgn(om.cost.data.kk, s2, cp.kk); 0243 end 0244 if isfield(cp, 'mm') 0245 om.cost.data.mm = subsasgn(om.cost.data.mm, s2, cp.mm); 0246 end 0247 0248 %% update number of costs and cost sets 0249 om.cost.N = subsref(om.cost.idx.iN, s1); 0250 om.cost.NS = om.cost.NS + 1; 0251 0252 %% add to ordered list of cost sets 0253 om.cost.order(om.cost.NS).name = name; 0254 om.cost.order(om.cost.NS).idx = idx; 0255 end 0256 end