Home > matpower7.1 > mp-opt-model > lib > @opt_model > set_params.m

set_params

PURPOSE ^

SET_PARAMS Modifies parameters for variable, cost or constraint in model

SYNOPSIS ^

function om = set_params(om, st, name, idx, params, vals)

DESCRIPTION ^

SET_PARAMS  Modifies parameters for variable, cost or constraint in model

   This method can be used to modify parameters for an existing variable,
   constraint or cost in the model.

   OM.SET_PARAMS(SET_TYPE, NAME, PARAMS, VALS)
   OM.SET_PARAMS(SET_TYPE, NAME, IDX, PARAMS, VALS)

   Inputs:
       SET_TYPE : one of 'var', 'lin', 'nle', 'nli', 'nlc', 'qdc' for
           variables, linear constraints, nonlinear equality constraints,
           nonlinear inequality constraints, general nonlinear costs,
           and quadratic costs, respectively
       NAME : name of set
       IDX : index of named set (for an indexed set)
       PARAMS : can be one of three options:
           1 - 'all', indicating that VALS is a cell array whose elements
               correspond to the input parameters of the respective
               add_*() method
           2 - the name of a PARAM, VAL is the value of that parameter
           3 - a cell array of PARAM names, VALS is a cell array of
               corresponding values
           Note: Changing the dimension of a 'var' is not allowed
               and changing the #1 ('all') is the only option for 'nle', 'nli', and 'nlc'
       VALS : new value or cell array of new values for PARAMS

   Valid PARAM names:
       var - N, v0, vl, vu, vt
       lin - A, l, u, vs
       nle - N, fcn, hess, include, vs
       nli - N, fcn, hess, include, vs
       nlc - N, fcn, vs
       qdc - Q, c, k, vs

   Examples:
       om.set_params('var', 'v0', v0, 'Pg');
       om.set_params('lin', {'l', 'u'}, {l, u}, 'y', {2,3});
       om.set_params('nle', 'all', {N, @fcn, @hess, vs}, 'Pmis');

   See also OPT_MODEL, ADD_VAR, ADD_LIN_CONSTRAINT, ADD_NLN_CONSTRAINT
            ADD_QUAD_COST and ADD_NLN_COST.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function om = set_params(om, st, name, idx, params, vals)
0002 %SET_PARAMS  Modifies parameters for variable, cost or constraint in model
0003 %
0004 %   This method can be used to modify parameters for an existing variable,
0005 %   constraint or cost in the model.
0006 %
0007 %   OM.SET_PARAMS(SET_TYPE, NAME, PARAMS, VALS)
0008 %   OM.SET_PARAMS(SET_TYPE, NAME, IDX, PARAMS, VALS)
0009 %
0010 %   Inputs:
0011 %       SET_TYPE : one of 'var', 'lin', 'nle', 'nli', 'nlc', 'qdc' for
0012 %           variables, linear constraints, nonlinear equality constraints,
0013 %           nonlinear inequality constraints, general nonlinear costs,
0014 %           and quadratic costs, respectively
0015 %       NAME : name of set
0016 %       IDX : index of named set (for an indexed set)
0017 %       PARAMS : can be one of three options:
0018 %           1 - 'all', indicating that VALS is a cell array whose elements
0019 %               correspond to the input parameters of the respective
0020 %               add_*() method
0021 %           2 - the name of a PARAM, VAL is the value of that parameter
0022 %           3 - a cell array of PARAM names, VALS is a cell array of
0023 %               corresponding values
0024 %           Note: Changing the dimension of a 'var' is not allowed
0025 %               and changing the #1 ('all') is the only option for 'nle', 'nli', and 'nlc'
0026 %       VALS : new value or cell array of new values for PARAMS
0027 %
0028 %   Valid PARAM names:
0029 %       var - N, v0, vl, vu, vt
0030 %       lin - A, l, u, vs
0031 %       nle - N, fcn, hess, include, vs
0032 %       nli - N, fcn, hess, include, vs
0033 %       nlc - N, fcn, vs
0034 %       qdc - Q, c, k, vs
0035 %
0036 %   Examples:
0037 %       om.set_params('var', 'v0', v0, 'Pg');
0038 %       om.set_params('lin', {'l', 'u'}, {l, u}, 'y', {2,3});
0039 %       om.set_params('nle', 'all', {N, @fcn, @hess, vs}, 'Pmis');
0040 %
0041 %   See also OPT_MODEL, ADD_VAR, ADD_LIN_CONSTRAINT, ADD_NLN_CONSTRAINT
0042 %            ADD_QUAD_COST and ADD_NLN_COST.
0043 
0044 %   MP-Opt-Model
0045 %   Copyright (c) 2008-2020, Power Systems Engineering Research Center (PSERC)
0046 %   by Ray Zimmerman, PSERC Cornell
0047 %
0048 %   This file is part of MP-Opt-Model.
0049 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0050 %   See https://github.com/MATPOWER/mp-opt-model for more info.
0051 
0052 if nargin < 6
0053     vals = params;
0054     params = idx;
0055     idx = {};
0056 end
0057 
0058 %% create default list of parameters to update based on set type & inputs
0059 switch st
0060     case 'var'
0061         default_params = {'N', 'v0', 'vl', 'vu', 'vt'};
0062     case 'lin'
0063         default_params = {'A', 'l', 'u', 'vs'};
0064     case {'nle', 'nli'}
0065         default_params = {'N', 'fcn', 'hess', 'vs'};
0066     case 'nlc'
0067         default_params = {'N', 'fcn', 'vs'};
0068     case 'qdc'
0069         default_params = {'Q', 'c', 'k', 'vs'};
0070     otherwise
0071         error('@opt_model/set_params: ''%s'' is not a valid SET_TYPE', st);
0072 end
0073 
0074 %% standardize provided arguments in cell arrays params, vals
0075 is_all = 0;     %% flag to indicate all params for set are being replaced
0076 if ischar(params)
0077     if strcmp(params, 'all')
0078         is_all = 1;
0079         np = length(vals);      %% number of parameter values provided
0080         params = default_params(1:np);
0081     else
0082         np = 1;                 %% number of parameter values provided
0083         params = {params};
0084         vals = {vals};
0085     end
0086 else
0087     np = length(vals);          %% number of parameter values provided
0088 end
0089 
0090 if ~isempty(idx)
0091     %% calls to substruct() are relatively expensive, so we pre-build the
0092     %% struct for addressing cell array fields
0093     %% sc = substruct('.', name, '{}', idx);
0094     sc = struct('type', {'.', '{}'}, 'subs', {name, idx});  %% cell array field
0095 end
0096 
0097 switch st
0098     case 'var'
0099         %% get current parameters
0100         [v0, vl, vu, vt] = om.params_var(name, idx);
0101         N0 = om.getN('var', name, idx);
0102         p = struct('N', N0, 'v0', v0, 'vl', vl, 'vu', vu, 'vt', vt);    %% current parameters
0103         u = struct('N',  0, 'v0',  0, 'vl',  0, 'vu',  0, 'vt',  0);    %% which ones to update
0104 
0105         %% replace with new parameters
0106         for k = 1:np
0107             p.(params{k}) = vals{k};
0108             u.(params{k}) = 1;
0109         end
0110         N = p.N;
0111 
0112         %% set missing default params for 'all'
0113         if is_all
0114             if np < 5
0115                 p.vt = 'C';
0116                 u.vt = 1;               %% update vt
0117                 if np < 4
0118                     p.vu = Inf(N, 1);
0119                     u.vu = 1;           %% update vu
0120                     if np < 3
0121                         p.vl = -Inf(N, 1);
0122                         u.vl = 1;       %% update vl
0123                         if np < 2
0124                             p.v0 = zeros(N, 1);
0125                             u.v0 = 1;   %% update v0
0126                         end
0127                     end
0128                 end
0129             end
0130         end
0131 
0132         %% check consistency of parameters
0133         %% no dimension change
0134         if N ~= N0
0135             error('@opt_model/set_params: dimension change for ''%s'' ''%s'' not allowed', st, nameidxstr(name, idx));
0136         end
0137 
0138         %% check sizes of new values of v0, vl, vu, vt
0139         for pn = {'v0', 'vl', 'vu', 'vt'}
0140             if u.(pn{1})
0141                 nn = length(p.(pn{1}));
0142                 if nn ~= N
0143                     if nn == 0
0144                         switch pn{1}
0145                             case 'v0'
0146                                 p.(pn{1}) = zeros(N, 0);
0147                             case 'vl'
0148                                 p.(pn{1}) = -Inf(N, 0);
0149                             case 'vu'
0150                                 p.(pn{1}) =  Inf(N, 0);
0151                             case 'vt'
0152                                 p.(pn{1}) = 'C';
0153                         end
0154                     elseif nn == 1
0155                         if pn{1} ~= 'vt'
0156                             p.(pn{1}) = p.(pn{1}) * ones(N, 1);   %% expand from scalar
0157                         end
0158                     else
0159                         error('@opt_model/set_params: parameter ''%s'' ''%s'' ''%s'' should have length %d (or 1)', st, nameidxstr(name, idx), pn{1}, N);
0160                     end
0161                 end
0162             end
0163         end
0164 
0165         %% assign new parameters
0166         if isempty(idx)     %% simple named set
0167             for k = 2:length(default_params)
0168                 pn = default_params{k};     %% param name
0169                 if u.(pn)   %% assign new val for this parameter
0170                     om.var.data.(pn).(name) = p.(pn);
0171                 end
0172             end
0173         else                %% indexed named set
0174             for k = 2:length(default_params)
0175                 pn = default_params{k};     %% param name
0176                 if u.(pn)   %% assign new val for this parameter
0177                     om.var.data.(pn) = subsasgn(om.var.data.(pn), sc, p.(pn));
0178                 end
0179             end
0180         end
0181     case 'lin'
0182         %% get current parameters
0183         [A, l, u, vs] = om.params_lin_constraint(name, idx);
0184         [N0, M0] = size(A);
0185         if isempty(vs), vs = {vs}; end
0186         p = struct('A', A, 'l', l, 'u', u, 'vs', vs);   %% current parameters
0187         u = struct('A', 0, 'l', 0, 'u', 0, 'vs',  0);   %% which ones to update
0188 
0189         %% replace with new parameters
0190         for k = 1:np
0191             p.(params{k}) = vals{k};
0192             u.(params{k}) = 1;
0193         end
0194 
0195         %% set missing default params for 'all'
0196         [N, M] = size(p.A);
0197         if is_all
0198             u.A = 1;            %% always update A
0199             u.l = 1;            %% alwaus update l
0200             if np < 4
0201                 p.vs = {};
0202                 u.vs = 1;       %% update vs
0203                 if np < 3
0204                     p.u = Inf(N, 1);
0205                     u.u = 1;    %% update u
0206                 end
0207             end
0208         end
0209 
0210         %% check consistency of parameters
0211         %% no dimension change unless 'all'
0212         if N ~= N0 && ~is_all
0213             error('@opt_model/set_params: dimension change for ''%s'' ''%s'' not allowed except for ''all''', st, nameidxstr(name, idx));
0214         end
0215 
0216         %% check sizes of new values of l, u
0217         for pn = {'l', 'u'}
0218             if u.(pn{1})
0219                 nn = length(p.(pn{1}));
0220                 if nn ~= N
0221                     if nn == 0
0222                         switch pn{1}
0223                             case 'l'
0224                                 p.(pn{1}) = -Inf(N, 0);
0225                             case 'u'
0226                                 p.(pn{1}) =  Inf(N, 0);
0227                         end
0228                     elseif nn == 1
0229                         p.(pn{1}) = p.(pn{1}) * ones(N, 1);   %% expand from scalar
0230                     else
0231                         error('@opt_model/set_params: parameter ''%s'' ''%s'' ''%s'' should have length %d (or 1)', st, nameidxstr(name, idx), pn{1}, N);
0232                     end
0233                 end
0234             end
0235         end
0236 
0237         %% check consistency of A and vs
0238         if u.A || u.vs
0239             p.vs = om.varsets_cell2struct(p.vs);
0240             nv = om.varsets_len(p.vs);      %% number of variables
0241             if M ~= nv
0242                 error('@opt_model/set_params: for ''%s'' ''%s'' number of columns of ''A'' (%d) must be consistent with ''vs'' (%d)', st, nameidxstr(name, idx), M, nv);
0243             end
0244         end
0245 
0246         %% assign new parameters
0247         if isempty(idx)     %% simple named set
0248             for k = 1:length(default_params)
0249                 pn = default_params{k};     %% param name
0250                 if u.(pn)   %% assign new val for this parameter
0251                     om.lin.data.(pn).(name) = p.(pn);
0252                 end
0253             end
0254         else                %% indexed named set
0255             for k = 1:length(default_params)
0256                 pn = default_params{k};     %% param name
0257                 if u.(pn)   %% assign new val for this parameter
0258                     om.lin.data.(pn) = subsasgn(om.lin.data.(pn), sc, p.(pn));
0259                 end
0260             end
0261         end
0262     case 'qdc'
0263         %% get current parameters
0264         [Q, c, kk, vs] = om.params_quad_cost(name, idx);
0265         [MQ0, NQ0] = size(Q);
0266         [Mc0, Nc0] = size(c);
0267         Nk0 = length(kk);
0268         nx0 = max([MQ0 Mc0 Nk0]);
0269         N0 = om.getN('qdc', name, idx);
0270         if isempty(vs), vs = {vs}; end
0271         p = struct('Q', Q, 'c', c, 'k', kk, 'vs', vs);  %% current parameters
0272         u = struct('Q', 0, 'c', 0, 'k',  0, 'vs',  0);  %% which ones to update
0273 
0274         %% replace with new parameters
0275         for k = 1:np
0276             p.(params{k}) = vals{k};
0277             u.(params{k}) = 1;
0278         end
0279 
0280         %% set missing default params for 'all'
0281         [MQ, NQ] = size(p.Q);
0282         [Mc, Nc] = size(p.c);
0283         Nk = length(p.k);
0284         nx = max([MQ Mc Nk]);
0285         if NQ == 1 || (isempty(p.Q) && (Nk > 1 || k == 0))
0286             %% Q is a column vector (cost is element-wise, i.e. a vector)
0287             %% OR Q is empty and k is either a vector or zero
0288             N = nx;
0289         else            %% Q is a square matrix (cost is a scalar)
0290             N = 1;
0291         end
0292         if is_all
0293             u.Q = 1;                %% always update Q
0294             if np < 4
0295                 p.vs = {};
0296                 u.vs = 1;           %% update vs
0297                 if np < 3
0298                     p.k = 0;
0299                     u.k = 1;        %% update k
0300                     if np < 2
0301                         p.c = [];
0302                         u.c = 1;    %% update c
0303                     end
0304                 end
0305             end
0306         end
0307 
0308         %% check consistency of parameters
0309         %% no dimension change unless 'all'
0310         if (N ~= N0 || nx ~= nx0) && ~is_all
0311             error('@opt_model/set_params: dimension change for ''%s'' ''%s'' not allowed except for ''all''', st, nameidxstr(name, idx));
0312         end
0313 
0314         %% Q and c can't both be empty
0315         if ~MQ && ~Mc
0316             error('@opt_model/set_params: ''%s'' ''%s'' : ''Q'' and ''c'' cannot both be empty', st, nameidxstr(name, idx));
0317         end
0318 
0319         %% check sizes of new values of Q, c, k
0320         if ~isempty(p.Q) && (MQ ~= nx || (MQ ~= NQ && NQ ~= 1) )
0321             error('@opt_model/set_params: ''%s'' ''%s'' : ''%s'' is expected to be (%d x %d)', st, nameidxstr(name, idx), 'Q', MQ, NQ);
0322         end
0323         if ~isempty(p.c) && Mc ~= nx
0324             error('@opt_model/set_params: ''%s'' ''%s'' : ''%s'' is expected to be (%d x %d)', st, nameidxstr(name, idx), 'c', Mc, 1);
0325         end
0326         if ~isempty(p.k) && any(p.k) && Nk ~= N && Nk ~= 1
0327             error('@opt_model/set_params: ''%s'' ''%s'' : ''%s'' is expected to be (%d x %d)', st, nameidxstr(name, idx), 'k', N, 1);
0328         end
0329 
0330         %% check consistency of Q, c, k and vs
0331         if u.Q || u.c || u.vs
0332             p.vs = om.varsets_cell2struct(p.vs);
0333             nv = om.varsets_len(p.vs);      %% number of variables
0334             if nx ~= nv
0335                 error('@opt_model/set_params: for ''%s'' ''%s'' dimensions of ''Q'', ''c'', ''k'' (%d) must be consistent with ''vs'' (%d)', st, nameidxstr(name, idx), nx, nv);
0336             end
0337         end
0338 
0339         %% assign new parameters
0340         if isempty(idx)     %% simple named set
0341             for k = 1:length(default_params)
0342                 pn = default_params{k};     %% param name
0343                 if u.(pn)   %% assign new val for this parameter
0344                     om.qdc.data.(pn).(name) = p.(pn);
0345                 end
0346             end
0347         else                %% indexed named set
0348             for k = 1:length(default_params)
0349                 pn = default_params{k};     %% param name
0350                 if u.(pn)   %% assign new val for this parameter
0351                     om.qdc.data.(pn) = subsasgn(om.qdc.data.(pn), sc, p.(pn));
0352                 end
0353             end
0354         end
0355     case {'nle', 'nli'}
0356         %% get current parameters
0357         if isempty(idx)
0358             [N0, fcn, hess, vs, include] = om.params_nln_constraint(st(3) == 'e', name, idx);
0359         else
0360             [N0, fcn, hess, vs] = om.params_nln_constraint(st(3) == 'e', name, idx);
0361             include = '';
0362         end
0363         if isempty(vs), vs = {vs}; end
0364         p = struct('N', N0, 'fcn', fcn, 'hess', hess, 'vs', vs);    %% current parameters
0365         u = struct('N',  0, 'fcn',   0, 'hess',    0, 'vs',  0);    %% which ones to update
0366 
0367         %% replace with new parameters
0368         for k = 1:np
0369             p.(params{k}) = vals{k};
0370             u.(params{k}) = 1;
0371         end
0372         N = p.N;
0373 
0374         %% set missing default params for 'all'
0375         if is_all
0376             u.N    = 1;         %% always update N
0377             u.fcn  = 1;         %% alwaus update fcn
0378             u.hess = 1;         %% alwaus update hess
0379             if np < 4
0380                 p.vs = {};
0381                 u.vs = 1;       %% update vs
0382             end
0383         end
0384 
0385         %% check consistency of parameters
0386         %% no dimension change unless 'all'
0387         if N ~= N0 && ~is_all
0388             error('@opt_model/set_params: dimension change for ''%s'' ''%s'' not allowed except for ''all''', st, nameidxstr(name, idx));
0389         end
0390 
0391         %% included constraints not yet implemented
0392         if ~isempty(include)
0393             error('@opt_model/set_params: modifications for ''%s'' ''%s'' not (yet) supported since it includes evaluation of other constraints', st, nameidxstr(name, idx));
0394         end
0395 
0396         %% convert vs to struct
0397         if u.vs
0398             p.vs = om.varsets_cell2struct(p.vs);
0399         end
0400 
0401         %% assign new parameters
0402         if isempty(idx)     %% simple named set
0403             for k = 2:length(default_params)
0404                 pn = default_params{k};     %% param name
0405                 if u.(pn)   %% assign new val for this parameter
0406                     om.(st).data.(pn).(name) = p.(pn);
0407                 end
0408             end
0409         else                %% indexed named set
0410             for k = 2:length(default_params)
0411                 pn = default_params{k};     %% param name
0412                 if u.(pn)   %% assign new val for this parameter
0413                     om.(st).data.(pn) = subsasgn(om.(st).data.(pn), sc, p.(pn));
0414                 end
0415             end
0416         end
0417     case 'nlc'
0418         %% get current parameters
0419         [N0, fcn, vs] = om.params_nln_cost(name, idx);
0420         if isempty(vs), vs = {vs}; end
0421         p = struct('N', N0, 'fcn', fcn, 'vs', vs);  %% current parameters
0422         u = struct('N',  0, 'fcn',   0, 'vs',  0);  %% which ones to update
0423 
0424         %% replace with new parameters
0425         for k = 1:np
0426             p.(params{k}) = vals{k};
0427             u.(params{k}) = 1;
0428         end
0429         N = p.N;
0430 
0431         %% set missing default params for 'all'
0432         if is_all
0433             u.N   = 1;          %% always update N
0434             u.fcn = 1;          %% alwaus update fcn
0435             if np < 3
0436                 p.vs = {};
0437                 u.vs = 1;       %% update vs
0438             end
0439         end
0440 
0441         %% check consistency of parameters
0442         %% no dimension change unless 'all'
0443         if N ~= N0 && ~is_all
0444             error('@opt_model/set_params: dimension change for ''%s'' ''%s'' not allowed except for ''all''', st, nameidxstr(name, idx));
0445         end
0446 
0447         %% vector valued costs not yet implemented
0448         if N ~= 1
0449             error('@opt_model/set_params: vector value for ''%s'' ''%s'' not yet implemented', st, nameidxstr(name, idx));
0450         end
0451 
0452         %% assign new parameters
0453         if isempty(idx)     %% simple named set
0454             for k = 2:length(default_params)
0455                 pn = default_params{k};     %% param name
0456                 if u.(pn)   %% assign new val for this parameter
0457                     om.nlc.data.(pn).(name) = p.(pn);
0458                 end
0459             end
0460         else                %% indexed named set
0461             for k = 2:length(default_params)
0462                 pn = default_params{k};     %% param name
0463                 if u.(pn)   %% assign new val for this parameter
0464                     om.nlc.data.(pn) = subsasgn(om.nlc.data.(pn), sc, p.(pn));
0465                 end
0466             end
0467         end
0468     otherwise
0469         error('@opt_model/set_params: ''%s'' is not a valid SET_TYPE', st);
0470 end
0471 
0472 %% update dimensions and indexing, if necessary
0473 dN = N - N0;
0474 if is_all && dN
0475     %% calls to substruct() are relatively expensive, so we pre-build the
0476     %% struct for addressing num array fields
0477     %% sn = substruct('.', name, '()', idx);
0478     sn = struct('type', {'.', '()'}, 'subs', {'', 1});  %% num array field
0479     om_ff = om.(st);
0480     update = 0;             %% not yet reached set being updated
0481     update_i1 = 0;          %% flag to indicate whether to update i1
0482     for k = 1:om_ff.NS
0483         o = om_ff.order(k);
0484         if ~update && strcmp(o.name, name) && isequal(o.idx, idx)
0485             update = 1;     %% arrived at set being updated
0486         end
0487         if update
0488             if isempty(o.idx)   %% simple named set
0489                 if update_i1
0490                     om_ff.idx.i1.(o.name) = om_ff.idx.i1.(o.name) + dN;
0491                 else
0492                     om_ff.idx.N.(o.name) = om_ff.idx.N.(o.name) + dN;
0493                 end
0494                 om_ff.idx.iN.(o.name) = om_ff.idx.iN.(o.name) + dN;
0495             else                %% indexed named set
0496                 sn(1).subs = o.name;
0497                 sn(2).subs = o.idx;
0498                 if update_i1
0499                     v = subsref(om_ff.idx.i1, sn);
0500                     om_ff.idx.i1 = subsasgn(om_ff.idx.i1, sn, v + dN);
0501                 else
0502                     v = subsref(om_ff.idx.N, sn);
0503                     om_ff.idx.N = subsasgn(om_ff.idx.N, sn, v + dN);
0504                 end
0505                 v = subsref(om_ff.idx.iN, sn);
0506                 om_ff.idx.iN = subsasgn(om_ff.idx.iN, sn, v + dN);
0507             end
0508             update_i1 = 1;  %% update i1 from here on out
0509         end
0510     end
0511     om_ff.N = om_ff.N + dN;
0512     om.(st) = om_ff;
0513 end
0514 
0515 
0516 function str = nameidxstr(name, idx)
0517 str = sprintf('%s%s', name, idxstr(idx));
0518 
0519 function str = idxstr(idx)
0520 if isempty(idx)
0521     str = '';
0522 elseif length(idx) == 1
0523     str = sprintf('(%d)', idx{1});
0524 else
0525     str = ['(' sprintf('%d', idx{1}) sprintf(',%d', idx{2:end}) ')'];
0526 end

Generated on Fri 09-Oct-2020 11:21:31 by m2html © 2005