INT2EXT Converts internal to external bus numbering. This function performs several different tasks, depending on the arguments passed. 1. [BUS, GEN, BRANCH, AREAS] = INT2EXT(I2E, BUS, GEN, BRANCH, AREAS) [BUS, GEN, BRANCH] = INT2EXT(I2E, BUS, GEN, BRANCH) Converts from the consecutive internal bus numbers back to the originals using the mapping provided by the I2E vector returned from EXT2INT, where EXTERNAL_BUS_NUMBER = I2E(INTERNAL_BUS_NUMBER). Examples: [bus, gen, branch, areas] = int2ext(i2e, bus, gen, branch, areas); [bus, gen, branch] = int2ext(i2e, bus, gen, branch); 2. MPC = INT2EXT(MPC) If the input is a single MATPOWER case struct, then it restores all buses, generators and branches that were removed because of being isolated or off-line, and reverts to the original generator ordering and original bus numbering. This requires that the 'order' field created by EXT2INT be in place. Example: mpc = int2ext(mpc); 3. VAL = INT2EXT(MPC, VAL, OLDVAL, ORDERING) VAL = INT2EXT(MPC, VAL, OLDVAL, ORDERING, DIM) MPC = INT2EXT(MPC, FIELD, ORDERING) MPC = INT2EXT(MPC, FIELD, ORDERING, DIM) For a case struct using internal indexing, this function can be used to convert other data structures as well by passing in 2 to 4 extra parameters in addition to the case struct. If the values passed in the 2nd argument (VAL) is a column vector, it will be converted according to the ordering specified by the 4th argument (ORDERING, described below). If VAL is an n-dimensional matrix, then the optional 5th argument (DIM, default = 1) can be used to specify which dimension to reorder. The 3rd argument (OLDVAL) is used to initialize the return value before converting VAL to external indexing. In particular, any data corresponding to off-line gens or branches or isolated buses or any connected gens or branches will be taken from OLDVAL, with VAL supplying the rest of the returned data. If the 2nd argument is a string or cell array of strings, it specifies a field in the case struct whose value should be converted as described above. In this case, the corresponding OLDVAL is taken from where it was stored by EXT2INT in MPC.ORDER.EXT and the updated case struct is returned. If FIELD is a cell array of strings, they specify nested fields. The ORDERING argument is used to indicate whether the data corresponds to bus-, gen- or branch-ordered data. It can be one of the following three strings: 'bus', 'gen' or 'branch'. For data structures with multiple blocks of data, ordered by bus, gen or branch, they can be converted with a single call by specifying ORDERING as a cell array of strings. Any extra elements, rows, columns, etc. beyond those indicated in ORDERING, are not disturbed. Examples: A_ext = int2ext(mpc, A_int, A_orig, {'bus','bus','gen','gen'}, 2); Converts an A matrix for user-supplied OPF constraints from internal to external ordering, where the columns of the A matrix correspond to bus voltage angles, then voltage magnitudes, then generator real power injections and finally generator reactive power injections. gencost_ext = int2ext(mpc, gencost_int, gencost_orig, {'gen','gen'}, 1); Converts a GENCOST matrix that has both real and reactive power costs (in rows 1--ng and ng+1--2*ng, respectively). mpc = int2ext(mpc, {'reserves', 'cost'}, 'gen'); Reorders rows of mpc.reserves.cost to match external generator ordering. mpc = int2ext(mpc, {'reserves', 'zones'}, 'gen', 2); Reorders columns of mpc.reserves.zones to match external generator ordering. See also EXT2INT.
0001 function [bus, gen, branch, areas] = int2ext(i2e, bus, gen, branch, areas) 0002 %INT2EXT Converts internal to external bus numbering. 0003 % 0004 % This function performs several different tasks, depending on the 0005 % arguments passed. 0006 % 0007 % 1. [BUS, GEN, BRANCH, AREAS] = INT2EXT(I2E, BUS, GEN, BRANCH, AREAS) 0008 % [BUS, GEN, BRANCH] = INT2EXT(I2E, BUS, GEN, BRANCH) 0009 % 0010 % Converts from the consecutive internal bus numbers back to the originals 0011 % using the mapping provided by the I2E vector returned from EXT2INT, 0012 % where EXTERNAL_BUS_NUMBER = I2E(INTERNAL_BUS_NUMBER). 0013 % 0014 % Examples: 0015 % [bus, gen, branch, areas] = int2ext(i2e, bus, gen, branch, areas); 0016 % [bus, gen, branch] = int2ext(i2e, bus, gen, branch); 0017 % 0018 % 2. MPC = INT2EXT(MPC) 0019 % 0020 % If the input is a single MATPOWER case struct, then it restores all 0021 % buses, generators and branches that were removed because of being 0022 % isolated or off-line, and reverts to the original generator ordering 0023 % and original bus numbering. This requires that the 'order' field 0024 % created by EXT2INT be in place. 0025 % 0026 % Example: 0027 % mpc = int2ext(mpc); 0028 % 0029 % 3. VAL = INT2EXT(MPC, VAL, OLDVAL, ORDERING) 0030 % VAL = INT2EXT(MPC, VAL, OLDVAL, ORDERING, DIM) 0031 % MPC = INT2EXT(MPC, FIELD, ORDERING) 0032 % MPC = INT2EXT(MPC, FIELD, ORDERING, DIM) 0033 % 0034 % For a case struct using internal indexing, this function can be 0035 % used to convert other data structures as well by passing in 2 to 4 0036 % extra parameters in addition to the case struct. If the values passed 0037 % in the 2nd argument (VAL) is a column vector, it will be converted 0038 % according to the ordering specified by the 4th argument (ORDERING, 0039 % described below). If VAL is an n-dimensional matrix, then the 0040 % optional 5th argument (DIM, default = 1) can be used to specify 0041 % which dimension to reorder. The 3rd argument (OLDVAL) is used to 0042 % initialize the return value before converting VAL to external 0043 % indexing. In particular, any data corresponding to off-line gens 0044 % or branches or isolated buses or any connected gens or branches 0045 % will be taken from OLDVAL, with VAL supplying the rest of the 0046 % returned data. 0047 % 0048 % If the 2nd argument is a string or cell array of strings, it 0049 % specifies a field in the case struct whose value should be 0050 % converted as described above. In this case, the corresponding 0051 % OLDVAL is taken from where it was stored by EXT2INT in 0052 % MPC.ORDER.EXT and the updated case struct is returned. 0053 % If FIELD is a cell array of strings, they specify nested fields. 0054 % 0055 % The ORDERING argument is used to indicate whether the data 0056 % corresponds to bus-, gen- or branch-ordered data. It can be one 0057 % of the following three strings: 'bus', 'gen' or 'branch'. For 0058 % data structures with multiple blocks of data, ordered by bus, 0059 % gen or branch, they can be converted with a single call by 0060 % specifying ORDERING as a cell array of strings. 0061 % 0062 % Any extra elements, rows, columns, etc. beyond those indicated 0063 % in ORDERING, are not disturbed. 0064 % 0065 % Examples: 0066 % A_ext = int2ext(mpc, A_int, A_orig, {'bus','bus','gen','gen'}, 2); 0067 % 0068 % Converts an A matrix for user-supplied OPF constraints from 0069 % internal to external ordering, where the columns of the A 0070 % matrix correspond to bus voltage angles, then voltage 0071 % magnitudes, then generator real power injections and finally 0072 % generator reactive power injections. 0073 % 0074 % gencost_ext = int2ext(mpc, gencost_int, gencost_orig, {'gen','gen'}, 1); 0075 % 0076 % Converts a GENCOST matrix that has both real and reactive power 0077 % costs (in rows 1--ng and ng+1--2*ng, respectively). 0078 % 0079 % mpc = int2ext(mpc, {'reserves', 'cost'}, 'gen'); 0080 % 0081 % Reorders rows of mpc.reserves.cost to match external generator 0082 % ordering. 0083 % 0084 % mpc = int2ext(mpc, {'reserves', 'zones'}, 'gen', 2); 0085 % 0086 % Reorders columns of mpc.reserves.zones to match external 0087 % generator ordering. 0088 % 0089 % See also EXT2INT. 0090 0091 % MATPOWER 0092 % $Id: int2ext.m,v 1.17 2010/04/26 19:45:25 ray Exp $ 0093 % by Ray Zimmerman, PSERC Cornell 0094 % Copyright (c) 1996-2010 by Power System Engineering Research Center (PSERC) 0095 % 0096 % This file is part of MATPOWER. 0097 % See http://www.pserc.cornell.edu/matpower/ for more info. 0098 % 0099 % MATPOWER is free software: you can redistribute it and/or modify 0100 % it under the terms of the GNU General Public License as published 0101 % by the Free Software Foundation, either version 3 of the License, 0102 % or (at your option) any later version. 0103 % 0104 % MATPOWER is distributed in the hope that it will be useful, 0105 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0106 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0107 % GNU General Public License for more details. 0108 % 0109 % You should have received a copy of the GNU General Public License 0110 % along with MATPOWER. If not, see <http://www.gnu.org/licenses/>. 0111 % 0112 % Additional permission under GNU GPL version 3 section 7 0113 % 0114 % If you modify MATPOWER, or any covered work, to interface with 0115 % other modules (such as MATLAB code and MEX-files) available in a 0116 % MATLAB(R) or comparable environment containing parts covered 0117 % under other licensing terms, the licensors of MATPOWER grant 0118 % you additional permission to convey the resulting work. 0119 0120 if isstruct(i2e) 0121 mpc = i2e; 0122 if nargin == 1 0123 if ~isfield(mpc, 'order') 0124 error('int2ext: mpc does not have the ''order'' field require for conversion back to external numbering.'); 0125 end 0126 o = mpc.order; 0127 0128 if o.state == 'i' 0129 %% define names for columns to data matrices 0130 [PQ, PV, REF, NONE, BUS_I] = idx_bus; 0131 GEN_BUS = idx_gen; 0132 [F_BUS, T_BUS] = idx_brch; 0133 [AREA_I, PRICE_REF_BUS] = idx_area; 0134 0135 %% execute userfcn callbacks for 'int2ext' stage 0136 if isfield(mpc, 'userfcn') 0137 mpc = run_userfcn(mpc.userfcn, 'int2ext', mpc); 0138 end 0139 0140 %% save data matrices with internal ordering & restore originals 0141 o.int.bus = mpc.bus; 0142 o.int.branch = mpc.branch; 0143 o.int.gen = mpc.gen; 0144 mpc.bus = o.ext.bus; 0145 mpc.branch = o.ext.branch; 0146 mpc.gen = o.ext.gen; 0147 if isfield(mpc, 'gencost') 0148 o.int.gencost = mpc.gencost; 0149 mpc.gencost = o.ext.gencost; 0150 end 0151 if isfield(mpc, 'areas') 0152 o.int.areas = mpc.areas; 0153 mpc.areas = o.ext.areas; 0154 end 0155 if isfield(mpc, 'A') 0156 o.int.A = mpc.A; 0157 mpc.A = o.ext.A; 0158 end 0159 if isfield(mpc, 'N') 0160 o.int.N = mpc.N; 0161 mpc.N = o.ext.N; 0162 end 0163 0164 %% update data (in bus, branch and gen only) 0165 mpc.bus(o.bus.status.on, :) = o.int.bus; 0166 mpc.branch(o.branch.status.on, :) = o.int.branch; 0167 mpc.gen(o.gen.status.on, :) = o.int.gen(o.gen.i2e, :); 0168 if isfield(mpc, 'areas') 0169 mpc.areas(o.areas.status.on, :) = o.int.areas; 0170 end 0171 0172 %% revert to original bus numbers 0173 mpc.bus(o.bus.status.on, BUS_I) = ... 0174 o.bus.i2e( mpc.bus(o.bus.status.on, BUS_I) ); 0175 mpc.branch(o.branch.status.on, F_BUS) = ... 0176 o.bus.i2e( mpc.branch(o.branch.status.on, F_BUS) ); 0177 mpc.branch(o.branch.status.on, T_BUS) = ... 0178 o.bus.i2e( mpc.branch(o.branch.status.on, T_BUS) ); 0179 mpc.gen(o.gen.status.on, GEN_BUS) = ... 0180 o.bus.i2e( mpc.gen(o.gen.status.on, GEN_BUS) ); 0181 if isfield(mpc, 'areas') 0182 mpc.areas(o.areas.status.on, PRICE_REF_BUS) = ... 0183 o.bus.i2e( mpc.areas(o.areas.status.on, PRICE_REF_BUS) ); 0184 end 0185 0186 if isfield(o, 'ext') 0187 o = rmfield(o, 'ext'); 0188 end 0189 o.state = 'e'; 0190 mpc.order = o; 0191 else 0192 error('int2ext: mpc claims it is already using external numbering.'); 0193 end 0194 0195 bus = mpc; 0196 else %% convert extra data 0197 if ischar(bus) || iscell(bus) %% field 0198 field = bus; 0199 ordering = gen; 0200 if nargin > 3 0201 dim = branch; 0202 else 0203 dim = 1; 0204 end 0205 if ischar(field) 0206 mpc.order.int.(field) = mpc.(field); 0207 mpc.(field) = int2ext(mpc, mpc.(field), ... 0208 mpc.order.ext.(field), ordering, dim); 0209 else 0210 for k = 1:length(field) 0211 s(k).type = '.'; 0212 s(k).subs = field{k}; 0213 end 0214 if ~isfield(mpc.order, 'int') 0215 mpc.order.int = []; 0216 end 0217 mpc.order.int = subsasgn(mpc.order.int, s, subsref(mpc, s)); 0218 mpc = subsasgn(mpc, s, int2ext(mpc, subsref(mpc, s), ... 0219 subsref(mpc.order.ext, s), ordering, dim)); 0220 end 0221 bus = mpc; 0222 else %% value 0223 val = bus; 0224 oldval = gen; 0225 ordering = branch; 0226 o = mpc.order; 0227 if nargin > 4 0228 dim = areas; 0229 else 0230 dim = 1; 0231 end 0232 if ischar(ordering) %% single set 0233 if strcmp(ordering, 'gen') 0234 v = get_reorder(val, o.(ordering).i2e, dim); 0235 else 0236 v = val; 0237 end 0238 bus = set_reorder(oldval, v, o.(ordering).status.on, dim); 0239 else %% multiple sets 0240 be = 0; %% base, external indexing 0241 bi = 0; %% base, internal indexing 0242 for k = 1:length(ordering) 0243 ne = size(o.ext.(ordering{k}), 1); 0244 ni = size(mpc.(ordering{k}), 1); 0245 v = get_reorder(val, bi+(1:ni), dim); 0246 oldv = get_reorder(oldval, be+(1:ne), dim); 0247 new_v{k} = int2ext(mpc, v, oldv, ordering{k}, dim); 0248 be = be + ne; 0249 bi = bi + ni; 0250 end 0251 ni = size(val, dim); 0252 if ni > bi %% the rest 0253 v = get_reorder(val, bi+1:ni, dim); 0254 new_v{length(new_v)+1} = v; 0255 end 0256 bus = cat(dim, new_v{:}); 0257 end 0258 end 0259 end 0260 else %% old form 0261 %% define names for columns to data matrices 0262 [PQ, PV, REF, NONE, BUS_I] = idx_bus; 0263 [GEN_BUS] = idx_gen; 0264 [F_BUS, T_BUS] = idx_brch; 0265 [AREA_I, PRICE_REF_BUS] = idx_area; 0266 0267 bus(:, BUS_I) = i2e( bus(:, BUS_I) ); 0268 gen(:, GEN_BUS) = i2e( gen(:, GEN_BUS) ); 0269 branch(:, F_BUS) = i2e( branch(:, F_BUS) ); 0270 branch(:, T_BUS) = i2e( branch(:, T_BUS) ); 0271 if nargin > 4 && nargout > 3 && ~isempty(areas) 0272 areas(:, PRICE_REF_BUS) = i2e( areas(:, PRICE_REF_BUS) ); 0273 end 0274 end