0001 function om = set_params(om, st, name, idx, params, vals)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 if nargin < 6
0053 vals = params;
0054 params = idx;
0055 idx = {};
0056 end
0057
0058
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
0075 is_all = 0;
0076 if ischar(params)
0077 if strcmp(params, 'all')
0078 is_all = 1;
0079 np = length(vals);
0080 params = default_params(1:np);
0081 else
0082 np = 1;
0083 params = {params};
0084 vals = {vals};
0085 end
0086 else
0087 np = length(vals);
0088 end
0089
0090 if ~isempty(idx)
0091
0092
0093
0094 sc = struct('type', {'.', '{}'}, 'subs', {name, idx});
0095 end
0096
0097 switch st
0098 case 'var'
0099
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);
0103 u = struct('N', 0, 'v0', 0, 'vl', 0, 'vu', 0, 'vt', 0);
0104
0105
0106 for k = 1:np
0107 p.(params{k}) = vals{k};
0108 u.(params{k}) = 1;
0109 end
0110 N = p.N;
0111
0112
0113 if is_all
0114 if np < 5
0115 p.vt = 'C';
0116 u.vt = 1;
0117 if np < 4
0118 p.vu = Inf(N, 1);
0119 u.vu = 1;
0120 if np < 3
0121 p.vl = -Inf(N, 1);
0122 u.vl = 1;
0123 if np < 2
0124 p.v0 = zeros(N, 1);
0125 u.v0 = 1;
0126 end
0127 end
0128 end
0129 end
0130 end
0131
0132
0133
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
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);
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
0166 if isempty(idx)
0167 for k = 2:length(default_params)
0168 pn = default_params{k};
0169 if u.(pn)
0170 om.var.data.(pn).(name) = p.(pn);
0171 end
0172 end
0173 else
0174 for k = 2:length(default_params)
0175 pn = default_params{k};
0176 if u.(pn)
0177 om.var.data.(pn) = subsasgn(om.var.data.(pn), sc, p.(pn));
0178 end
0179 end
0180 end
0181 case 'lin'
0182
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);
0187 u = struct('A', 0, 'l', 0, 'u', 0, 'vs', 0);
0188
0189
0190 for k = 1:np
0191 p.(params{k}) = vals{k};
0192 u.(params{k}) = 1;
0193 end
0194
0195
0196 [N, M] = size(p.A);
0197 if is_all
0198 u.A = 1;
0199 u.l = 1;
0200 if np < 4
0201 p.vs = {};
0202 u.vs = 1;
0203 if np < 3
0204 p.u = Inf(N, 1);
0205 u.u = 1;
0206 end
0207 end
0208 end
0209
0210
0211
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
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);
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
0238 if u.A || u.vs
0239 p.vs = om.varsets_cell2struct(p.vs);
0240 nv = om.varsets_len(p.vs);
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
0247 if isempty(idx)
0248 for k = 1:length(default_params)
0249 pn = default_params{k};
0250 if u.(pn)
0251 om.lin.data.(pn).(name) = p.(pn);
0252 end
0253 end
0254 else
0255 for k = 1:length(default_params)
0256 pn = default_params{k};
0257 if u.(pn)
0258 om.lin.data.(pn) = subsasgn(om.lin.data.(pn), sc, p.(pn));
0259 end
0260 end
0261 end
0262 case 'qdc'
0263
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);
0272 u = struct('Q', 0, 'c', 0, 'k', 0, 'vs', 0);
0273
0274
0275 for k = 1:np
0276 p.(params{k}) = vals{k};
0277 u.(params{k}) = 1;
0278 end
0279
0280
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
0287
0288 N = nx;
0289 else
0290 N = 1;
0291 end
0292 if is_all
0293 u.Q = 1;
0294 if np < 4
0295 p.vs = {};
0296 u.vs = 1;
0297 if np < 3
0298 p.k = 0;
0299 u.k = 1;
0300 if np < 2
0301 p.c = [];
0302 u.c = 1;
0303 end
0304 end
0305 end
0306 end
0307
0308
0309
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
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
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
0331 if u.Q || u.c || u.vs
0332 p.vs = om.varsets_cell2struct(p.vs);
0333 nv = om.varsets_len(p.vs);
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
0340 if isempty(idx)
0341 for k = 1:length(default_params)
0342 pn = default_params{k};
0343 if u.(pn)
0344 om.qdc.data.(pn).(name) = p.(pn);
0345 end
0346 end
0347 else
0348 for k = 1:length(default_params)
0349 pn = default_params{k};
0350 if u.(pn)
0351 om.qdc.data.(pn) = subsasgn(om.qdc.data.(pn), sc, p.(pn));
0352 end
0353 end
0354 end
0355 case {'nle', 'nli'}
0356
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);
0365 u = struct('N', 0, 'fcn', 0, 'hess', 0, 'vs', 0);
0366
0367
0368 for k = 1:np
0369 p.(params{k}) = vals{k};
0370 u.(params{k}) = 1;
0371 end
0372 N = p.N;
0373
0374
0375 if is_all
0376 u.N = 1;
0377 u.fcn = 1;
0378 u.hess = 1;
0379 if np < 4
0380 p.vs = {};
0381 u.vs = 1;
0382 end
0383 end
0384
0385
0386
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
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
0397 if u.vs
0398 p.vs = om.varsets_cell2struct(p.vs);
0399 end
0400
0401
0402 if isempty(idx)
0403 for k = 2:length(default_params)
0404 pn = default_params{k};
0405 if u.(pn)
0406 om.(st).data.(pn).(name) = p.(pn);
0407 end
0408 end
0409 else
0410 for k = 2:length(default_params)
0411 pn = default_params{k};
0412 if u.(pn)
0413 om.(st).data.(pn) = subsasgn(om.(st).data.(pn), sc, p.(pn));
0414 end
0415 end
0416 end
0417 case 'nlc'
0418
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);
0422 u = struct('N', 0, 'fcn', 0, 'vs', 0);
0423
0424
0425 for k = 1:np
0426 p.(params{k}) = vals{k};
0427 u.(params{k}) = 1;
0428 end
0429 N = p.N;
0430
0431
0432 if is_all
0433 u.N = 1;
0434 u.fcn = 1;
0435 if np < 3
0436 p.vs = {};
0437 u.vs = 1;
0438 end
0439 end
0440
0441
0442
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
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
0453 if isempty(idx)
0454 for k = 2:length(default_params)
0455 pn = default_params{k};
0456 if u.(pn)
0457 om.nlc.data.(pn).(name) = p.(pn);
0458 end
0459 end
0460 else
0461 for k = 2:length(default_params)
0462 pn = default_params{k};
0463 if u.(pn)
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
0473 dN = N - N0;
0474 if is_all && dN
0475
0476
0477
0478 sn = struct('type', {'.', '()'}, 'subs', {'', 1});
0479 om_ff = om.(st);
0480 update = 0;
0481 update_i1 = 0;
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;
0486 end
0487 if update
0488 if isempty(o.idx)
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
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;
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