PARAMS_LIN_CONSTRAINT Builds and returns linear constraint parameters. [A, L, U] = OM.PARAMS_LIN_CONSTRAINT() [A, L, U] = OM.PARAMS_LIN_CONSTRAINT(NAME) [A, L, U] = OM.PARAMS_LIN_CONSTRAINT(NAME, IDX_LIST) [A, L, U, VS] = OM.PARAMS_LIN_CONSTRAINT(...) [A, L, U, VS, I1, IN] = OM.PARAMS_LIN_CONSTRAINT(...) With no input parameters, it assembles and returns the parameters for the aggregate linear constraints from all linear constraint sets added using ADD_LIN_CONSTRAINT. The values of these parameters are cached for subsequent calls. The parameters are A, L and U where the linear constraint is of the form L <= A * x <= U If a NAME is provided then it simply returns the parameters for the corresponding named set. Likewise for indexed named sets specified by NAME and IDX_LIST. An optional 4th output argument VS indicates the variable sets used by this constraint set. The size of A will be consistent with VS. Optional 5th and 6th output arguments I1 and IN indicate the starting and ending row indices of the corresponding constraint set in the full aggregate constraint matrix. Examples: [A, l, u] = om.params_lin_constraint(); [A, l, u, vs, i1, iN] = om.params_lin_constraint('Pmis'); See also OPT_MODEL, ADD_LIN_CONSTRAINT.
0001 function [A, l, u, vs, i1, iN] = params_lin_constraint(om, name, idx) 0002 %PARAMS_LIN_CONSTRAINT Builds and returns linear constraint parameters. 0003 % [A, L, U] = OM.PARAMS_LIN_CONSTRAINT() 0004 % [A, L, U] = OM.PARAMS_LIN_CONSTRAINT(NAME) 0005 % [A, L, U] = OM.PARAMS_LIN_CONSTRAINT(NAME, IDX_LIST) 0006 % [A, L, U, VS] = OM.PARAMS_LIN_CONSTRAINT(...) 0007 % [A, L, U, VS, I1, IN] = OM.PARAMS_LIN_CONSTRAINT(...) 0008 % 0009 % With no input parameters, it assembles and returns the parameters 0010 % for the aggregate linear constraints from all linear constraint sets 0011 % added using ADD_LIN_CONSTRAINT. The values of these parameters are 0012 % cached for subsequent calls. The parameters are A, L and U where the 0013 % linear constraint is of the form 0014 % L <= A * x <= U 0015 % 0016 % If a NAME is provided then it simply returns the parameters for the 0017 % corresponding named set. Likewise for indexed named sets specified 0018 % by NAME and IDX_LIST. An optional 4th output argument VS indicates the 0019 % variable sets used by this constraint set. The size of A will be 0020 % consistent with VS. Optional 5th and 6th output arguments I1 and IN 0021 % indicate the starting and ending row indices of the corresponding 0022 % constraint set in the full aggregate constraint matrix. 0023 % 0024 % Examples: 0025 % [A, l, u] = om.params_lin_constraint(); 0026 % [A, l, u, vs, i1, iN] = om.params_lin_constraint('Pmis'); 0027 % 0028 % See also OPT_MODEL, ADD_LIN_CONSTRAINT. 0029 0030 % MP-Opt-Model 0031 % Copyright (c) 2008-2020, Power Systems Engineering Research Center (PSERC) 0032 % by Ray Zimmerman, PSERC Cornell 0033 % 0034 % This file is part of MP-Opt-Model. 0035 % Covered by the 3-clause BSD License (see LICENSE file for details). 0036 % See https://github.com/MATPOWER/mp-opt-model for more info. 0037 0038 if nargin > 1 %% individual set 0039 if nargin < 3 0040 idx = {}; 0041 end 0042 if isempty(idx) 0043 if numel(om.lin.idx.i1.(name)) == 1 %% simple named set 0044 A = om.lin.data.A.(name); 0045 l = om.lin.data.l.(name); 0046 u = om.lin.data.u.(name); 0047 if nargout > 3 0048 vs = om.lin.data.vs.(name); 0049 if nargout > 5 0050 i1 = om.lin.idx.i1.(name); %% starting row index 0051 iN = om.lin.idx.iN.(name); %% ending row index 0052 end 0053 end 0054 else %% indexing required 0055 error('@opt_model/params_lin_constraint: linear constraint set ''%s'' requires an IDX_LIST arg', name); 0056 end 0057 else 0058 % (calls to substruct() are relatively expensive ... 0059 % s = substruct('.', name, '{}', idx); 0060 % ... so replace it with these more efficient lines) 0061 sc = struct('type', {'.', '{}'}, 'subs', {name, idx}); 0062 A = subsref(om.lin.data.A, sc); 0063 l = subsref(om.lin.data.l, sc); 0064 u = subsref(om.lin.data.u, sc); 0065 if nargout > 3 0066 vs = subsref(om.lin.data.vs, sc); 0067 if nargout > 5 0068 sn = sc; sn(2).type = '()'; %% num array field 0069 i1 = subsref(om.lin.idx.i1, sn); %% starting row index 0070 iN = subsref(om.lin.idx.iN, sn); %% ending row index 0071 end 0072 end 0073 end 0074 else %% aggregate 0075 cache = om.lin.params; 0076 if isempty(cache) %% build the aggregate 0077 nx = om.var.N; %% number of variables 0078 nlin = om.lin.N; %% number of linear constraints 0079 if om.lin.NS < 25 || om.lin.NS < 100 && nx < 300 0080 %% METHOD 1: Add sparse matrices (original method) 0081 At = sparse(nx, nlin); %% transpose of constraint matrix 0082 u = Inf(nlin, 1); %% upper bound 0083 l = -u; %% lower bound 0084 0085 %% fill in each piece 0086 for k = 1:om.lin.NS 0087 name = om.lin.order(k).name; 0088 idx = om.lin.order(k).idx; 0089 [Ak, lk, uk, vs, i1, iN] = om.params_lin_constraint(name, idx); 0090 [mk, nk] = size(Ak); %% size of Ak 0091 if mk 0092 Akt_full = sparse(nx, nlin); 0093 if isempty(vs) 0094 if nk == nx %% full size 0095 Akt_full(:, i1:iN) = Ak'; 0096 else %% vars added since adding this constraint set 0097 Ak_all_cols = sparse(mk, nx); 0098 Ak_all_cols(:, 1:nk) = Ak; 0099 Akt_full(:, i1:iN) = Ak_all_cols'; 0100 end 0101 else 0102 jj = om.varsets_idx(vs); %% indices for var set 0103 Ak_all_cols = sparse(mk, nx); 0104 Ak_all_cols(:, jj) = Ak; 0105 Akt_full(:, i1:iN) = Ak_all_cols'; 0106 end 0107 At = At + Akt_full; 0108 l(i1:iN) = lk; 0109 u(i1:iN) = uk; 0110 end 0111 end 0112 A = At'; 0113 else 0114 %% METHOD 2: construct using single call to sparse() 0115 A_ijv = cell(om.lin.NS, 3); %% indices/values to construct A 0116 u = Inf(nlin, 1); %% upper bound 0117 l = -u; %% lower bound 0118 0119 %% fill in each piece 0120 for k = 1:om.lin.NS 0121 name = om.lin.order(k).name; 0122 idx = om.lin.order(k).idx; 0123 [Ak, lk, uk, vs, i1, iN] = om.params_lin_constraint(name, idx); 0124 [mk, nk] = size(Ak); %% size of Ak 0125 if mk 0126 % find nonzero sub indices and values 0127 [i, j, v] = find(Ak); 0128 if mk == 1 %% force col vectors for single row Ak 0129 i = i'; j = j'; v = v'; 0130 end 0131 0132 if isempty(vs) 0133 A_ijv(k,:) = {i+(i1-1), j, v}; 0134 else 0135 jj = om.varsets_idx(vs)'; %% indices for var set 0136 A_ijv(k,:) = {i+(i1-1), jj(j), v}; 0137 end 0138 l(i1:iN) = lk; 0139 u(i1:iN) = uk; 0140 end 0141 end 0142 A = sparse( vertcat(A_ijv{:,1}), ... 0143 vertcat(A_ijv{:,2}), ... 0144 vertcat(A_ijv{:,3}), nlin, nx); 0145 end 0146 0147 %% cache aggregated parameters 0148 om.lin.params = struct('A', A, 'l', l, 'u', u); 0149 else %% return cached values 0150 A = cache.A; 0151 l = cache.l; 0152 u = cache.u; 0153 end 0154 if nargout > 3 0155 vs = {}; 0156 end 0157 end