0001 classdef mp_idx_manager < handle 0002 %MP_IDX_MANAGER MATPOWER Index Manager abstract class 0003 % 0004 % A MATPOWER Index Manager object can be used to manage the indexing of 0005 % various named and indexed blocks of various set types, such as variables, 0006 % constraints, etc. This class helps keep track of the ordering and 0007 % indexing of the various blocks as they are added to the object. 0008 % 0009 % The types of named sets to be managed by the class are defined by the 0010 % DEF_SET_TYPES method, which assigns a struct to the 'set_types' field. 0011 % 0012 % Properties: 0013 % set_types - a struct defined by DEF_SET_TYPES method 0014 % userdata - a struct containing arbitrary data added by the user 0015 % 0016 % Private Methods 0017 % add_named_set - Adds named subset of a particular type to the 0018 % object. 0019 % 0020 % def_set_types - (must be implemented in the subclass) Returns a 0021 % struct defining the various set types, where the key is the 0022 % set type name, which must also be declared as a property in 0023 % the object's class, and the value is a string name used for 0024 % display purposes. 0025 % 0026 % E.g. 0027 % function obj = def_set_types(obj) 0028 % obj.set_types = struct(... 0029 % 'var', 'variable', ... 0030 % 'lin', 'linear constraint' ... 0031 % ); 0032 % end 0033 % 0034 % init_set_types - Used by object constructor to initializes the 0035 % structures needed to track the ordering and indexing of each 0036 % set type and can be overridden to initialize any additional 0037 % data to be stored with each block of each set type. 0038 % 0039 % valid_named_set_type - Returns a label for the given named set 0040 % type if valid, empty otherwise. 0041 % 0042 % Public Methods 0043 % add_<SET-TYPE> - (must be implemented in the subclass) Used to 0044 % add a block of the given set type to the object, using the 0045 % private ADD_NAMED_SET method internally followed by the 0046 % handling of any data specific to that set type. 0047 % 0048 % copy - Makes a shallow copy of the object. 0049 % 0050 % describe_idx - Identifies indices of a given set type. 0051 % E.g. variable 361 corresponds to Pg(68) 0052 % 0053 % display - (must be implemented in the subclass) Displays the 0054 % object (called automatically when you omit the semicolon at 0055 % the command-line). 0056 % 0057 % display_set - Prints to screen the indexing details for the 0058 % specified set type. Intended to be called by DISPLAY method. 0059 % 0060 % get_idx - Returns index structure(s) for specified set type(s), 0061 % with starting/ending indices and number of elements for 0062 % each named (and optionally indexed) block. 0063 % 0064 % get_userdata - Retreives values of user data stored in the object. 0065 % 0066 % get - Return the value of any individual field. 0067 % 0068 % getN - Returns the number of elements of any given set type, 0069 % optionally for a single named block. 0070 % 0071 % init_indexed_name - Initializes the dimensions for an indexed 0072 % named set. 0073 % 0074 % params_<SET-TYPE> - (must be implemented in the subclass) 0075 % Returns set-type-specific data for a given type. 0076 % 0077 % The following is the structure of the data in the object, using a set 0078 % type named 'var' for illustration. Each field of .idx or .data is a 0079 % struct whose field names are the names of the corresponding blocks of 0080 % elements of that type (e.g. variables, constraints, etc.). They are 0081 % found in order in the corresponding .order field. The description next 0082 % to these fields gives the meaning of the value for each named sub-field. 0083 % E.g. obj.var.data.v0.Pg contains a vector of initial values for the 'Pg' 0084 % block of variables. 0085 % 0086 % obj 0087 % .var - data for 'var' set type, e.g. variable sets that 0088 % make up the full optimization variable x 0089 % .idx 0090 % .i1 - starting index within x 0091 % .iN - ending index within x 0092 % .N - number of elements in this variable set 0093 % .N - total number of elements in x 0094 % .NS - number of variable sets or named blocks 0095 % .data - additional set-type-specific data for each block 0096 % .order - struct array of names/indices for variable 0097 % blocks in the order they appear in x 0098 % .name - name of the block, e.g. Pg 0099 % .idx - indices for name, {2,3} => Pg(2,3) 0100 % .userdata - any user defined data 0101 % .(user defined fields) 0102 0103 % MP-Opt-Model 0104 % Copyright (c) 2008-2020, Power Systems Engineering Research Center (PSERC) 0105 % by Ray Zimmerman, PSERC Cornell 0106 % 0107 % This file is part of MP-Opt-Model. 0108 % Covered by the 3-clause BSD License (see LICENSE file for details). 0109 % See https://github.com/MATPOWER/mp-opt-model for more info. 0110 0111 % es = struct(); 0112 0113 properties 0114 userdata; 0115 set_types; 0116 end %% properties 0117 0118 methods 0119 %% constructor 0120 function obj = mp_idx_manager(s) 0121 if nargin > 0 0122 if isa(s, 'mp_idx_manager') 0123 %% this copy constructor will not be inheritable under 0124 %% Octave until the fix has been included for: 0125 %% https://savannah.gnu.org/bugs/?52614 0126 if have_feature('octave') 0127 s1 = warning('query', 'Octave:classdef-to-struct'); 0128 warning('off', 'Octave:classdef-to-struct'); 0129 end 0130 props = fieldnames(s); 0131 if have_feature('octave') 0132 warning(s1.state, 'Octave:classdef-to-struct'); 0133 end 0134 for k = 1:length(props) 0135 obj.(props{k}) = s.(props{k}); 0136 end 0137 elseif isstruct(s) 0138 props = fieldnames(obj); 0139 for k = 1:length(props) 0140 if isfield(s, props{k}) 0141 obj.(props{k}) = s.(props{k}); 0142 end 0143 end 0144 else 0145 error('@mp_idx_manager/mp_idx_manager: input must be an ''mp_idx_manager'' object or a struct'); 0146 end 0147 end 0148 0149 obj.def_set_types(); 0150 % if isempty(obj.????) %% skip if constructed from existing object 0151 % obj.init_set_types();%% Octave 5.2 and earlier requires this 0152 % %% be called from the sub-class 0153 % %% constructor, since it alters fields of 0154 % %% an object not yet fully constructed. 0155 % %% Since been fixed: 0156 % %% https://savannah.gnu.org/bugs/?52614 0157 % end 0158 end 0159 0160 function obj = init_set_types(obj) 0161 %% base data struct for each type 0162 es = struct(); 0163 ds = struct( ... 0164 'idx', struct( ... 0165 'i1', es, ... 0166 'iN', es, ... 0167 'N', es ), ... 0168 'N', 0, ... 0169 'NS', 0, ... 0170 'order', struct( ... 0171 'name', [], ... 0172 'idx', [] ), ... 0173 'data', es ); 0174 0175 %% initialize each (set_type) field with base data structure 0176 for f = fieldnames(obj.set_types)' 0177 obj.(f{1}) = ds; 0178 end 0179 end 0180 0181 function new_obj = copy(obj) 0182 %% make shallow copy of object 0183 new_obj = eval(class(obj)); %% create new object 0184 if have_feature('octave') 0185 s1 = warning('query', 'Octave:classdef-to-struct'); 0186 warning('off', 'Octave:classdef-to-struct'); 0187 end 0188 props = fieldnames(obj); 0189 if have_feature('octave') 0190 warning(s1.state, 'Octave:classdef-to-struct'); 0191 end 0192 for k = 1:length(props) 0193 new_obj.(props{k}) = obj.(props{k}); 0194 end 0195 end 0196 0197 function display_set(obj, stype, sname) 0198 if nargin < 3 0199 sname = stype; 0200 end 0201 st = obj.(stype); %% data for set type of interest 0202 if st.NS 0203 fmt = '%-26s %6s %8s %8s %8s\n'; 0204 fprintf(fmt, sname, 'name', 'i1', 'iN', 'N'); 0205 fprintf(fmt, repmat('=', 1, length(sname)), '------', '-----', '-----', '------'); 0206 idx = st.idx; 0207 fmt = '%10d:%22s %8d %8d %8d\n'; 0208 for k = 1:st.NS 0209 name = st.order(k).name; 0210 if isempty(st.order(k).idx) 0211 fprintf(fmt, k, name, idx.i1.(name), idx.iN.(name), idx.N.(name)); 0212 else 0213 vsidx = st.order(k).idx; 0214 str = '%d'; for m = 2:length(vsidx), str = [str ',%d']; end 0215 s = substruct('.', name, '()', vsidx); 0216 nname = sprintf(['%s(' str, ')'], name, vsidx{:}); 0217 fprintf(fmt, k, nname, ... 0218 subsref(idx.i1, s), subsref(idx.iN, s), subsref(idx.N, s)); 0219 end 0220 end 0221 fmt = sprintf('%%10d = %%s.NS%%%dd = %%s.N\\n\\n', 35-length(stype)); 0222 fprintf(fmt, st.NS, stype, st.N, stype); 0223 else 0224 fprintf('%-26s : <none>\n', sname); 0225 end 0226 end 0227 0228 obj = add_named_set(obj, set_type, name, idx, N, varargin) 0229 0230 label = describe_idx(obj, set_type, idxs) 0231 0232 varargout = get_idx(obj, varargin) 0233 0234 rv = get_userdata(obj, name) 0235 0236 val = get(obj, varargin) 0237 0238 N = getN(obj, set_type, name, idx) 0239 0240 obj = init_indexed_name(obj, set_type, name, dim_list) 0241 0242 str = valid_named_set_type(obj, set_type) 0243 end %% methods 0244 end %% classdef