Home > matpower4.1 > ext2int.m

ext2int

PURPOSE ^

EXT2INT Converts external to internal indexing.

SYNOPSIS ^

function [i2e, bus, gen, branch, areas] = ext2int(bus, gen, branch, areas)

DESCRIPTION ^

EXT2INT   Converts external to internal indexing.

   This function has two forms, (1) the old form that operates on
   and returns individual matrices and (2) the new form that operates
   on and returns an entire MATPOWER case struct.

   1.  [I2E, BUS, GEN, BRANCH, AREAS] = EXT2INT(BUS, GEN, BRANCH, AREAS)
       [I2E, BUS, GEN, BRANCH] = EXT2INT(BUS, GEN, BRANCH)

   If the first argument is a matrix, it simply converts from (possibly
   non-consecutive) external bus numbers to consecutive internal bus
   numbers which start at 1. Changes are made to BUS, GEN, BRANCH and
   optionally AREAS matrices, which are returned along with a vector of
   indices I2E that can be passed to INT2EXT to perform the reverse
   conversion, where EXTERNAL_BUS_NUMBER = I2E(INTERNAL_BUS_NUMBER)

   Examples:
       [i2e, bus, gen, branch, areas] = ext2int(bus, gen, branch, areas);
       [i2e, bus, gen, branch] = ext2int(bus, gen, branch);

   2.  MPC = EXT2INT(MPC)

   If the input is a single MATPOWER case struct, then all isolated
   buses, off-line generators and branches are removed along with any
   generators, branches or areas connected to isolated buses. Then the
   buses are renumbered consecutively, beginning at 1, and the
   generators are sorted by increasing bus number. Any 'ext2int'
   callback routines registered in the case are also invoked
   automatically. All of the related indexing information and the
   original data matrices are stored in an 'order' field in the struct
   to be used by INT2EXT to perform the reverse conversions. If the
   case is already using internal numbering it is returned unchanged.

   Example:
       mpc = ext2int(mpc);

   The 'order' field of MPC used to store the indexing information
   needed for subsequent internal to external conversion is structured
   as:

       order
           state       'i' | 'e'
           ext | int
               areas
               bus
               branch
               gen
               gencost
               A
               N
           bus
               e2i
               i2e
               status
                   on
                   off
           gen
               e2i
               i2e
               status
                   on
                   off
           branch
               status
                   on
                   off
           areas
               status
                   on
                   off

   See also INT2EXT, E2I_FIELD, E2I_DATA.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [i2e, bus, gen, branch, areas] = ext2int(bus, gen, branch, areas)
0002 %EXT2INT   Converts external to internal indexing.
0003 %
0004 %   This function has two forms, (1) the old form that operates on
0005 %   and returns individual matrices and (2) the new form that operates
0006 %   on and returns an entire MATPOWER case struct.
0007 %
0008 %   1.  [I2E, BUS, GEN, BRANCH, AREAS] = EXT2INT(BUS, GEN, BRANCH, AREAS)
0009 %       [I2E, BUS, GEN, BRANCH] = EXT2INT(BUS, GEN, BRANCH)
0010 %
0011 %   If the first argument is a matrix, it simply converts from (possibly
0012 %   non-consecutive) external bus numbers to consecutive internal bus
0013 %   numbers which start at 1. Changes are made to BUS, GEN, BRANCH and
0014 %   optionally AREAS matrices, which are returned along with a vector of
0015 %   indices I2E that can be passed to INT2EXT to perform the reverse
0016 %   conversion, where EXTERNAL_BUS_NUMBER = I2E(INTERNAL_BUS_NUMBER)
0017 %
0018 %   Examples:
0019 %       [i2e, bus, gen, branch, areas] = ext2int(bus, gen, branch, areas);
0020 %       [i2e, bus, gen, branch] = ext2int(bus, gen, branch);
0021 %
0022 %   2.  MPC = EXT2INT(MPC)
0023 %
0024 %   If the input is a single MATPOWER case struct, then all isolated
0025 %   buses, off-line generators and branches are removed along with any
0026 %   generators, branches or areas connected to isolated buses. Then the
0027 %   buses are renumbered consecutively, beginning at 1, and the
0028 %   generators are sorted by increasing bus number. Any 'ext2int'
0029 %   callback routines registered in the case are also invoked
0030 %   automatically. All of the related indexing information and the
0031 %   original data matrices are stored in an 'order' field in the struct
0032 %   to be used by INT2EXT to perform the reverse conversions. If the
0033 %   case is already using internal numbering it is returned unchanged.
0034 %
0035 %   Example:
0036 %       mpc = ext2int(mpc);
0037 %
0038 %   The 'order' field of MPC used to store the indexing information
0039 %   needed for subsequent internal to external conversion is structured
0040 %   as:
0041 %
0042 %       order
0043 %           state       'i' | 'e'
0044 %           ext | int
0045 %               areas
0046 %               bus
0047 %               branch
0048 %               gen
0049 %               gencost
0050 %               A
0051 %               N
0052 %           bus
0053 %               e2i
0054 %               i2e
0055 %               status
0056 %                   on
0057 %                   off
0058 %           gen
0059 %               e2i
0060 %               i2e
0061 %               status
0062 %                   on
0063 %                   off
0064 %           branch
0065 %               status
0066 %                   on
0067 %                   off
0068 %           areas
0069 %               status
0070 %                   on
0071 %                   off
0072 %
0073 %   See also INT2EXT, E2I_FIELD, E2I_DATA.
0074 
0075 %   MATPOWER
0076 %   $Id: ext2int.m,v 1.20 2011/11/09 21:32:13 cvs Exp $
0077 %   by Ray Zimmerman, PSERC Cornell
0078 %   Copyright (c) 1996-2011 by Power System Engineering Research Center (PSERC)
0079 %
0080 %   This file is part of MATPOWER.
0081 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0082 %
0083 %   MATPOWER is free software: you can redistribute it and/or modify
0084 %   it under the terms of the GNU General Public License as published
0085 %   by the Free Software Foundation, either version 3 of the License,
0086 %   or (at your option) any later version.
0087 %
0088 %   MATPOWER is distributed in the hope that it will be useful,
0089 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0090 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0091 %   GNU General Public License for more details.
0092 %
0093 %   You should have received a copy of the GNU General Public License
0094 %   along with MATPOWER. If not, see <http://www.gnu.org/licenses/>.
0095 %
0096 %   Additional permission under GNU GPL version 3 section 7
0097 %
0098 %   If you modify MATPOWER, or any covered work, to interface with
0099 %   other modules (such as MATLAB code and MEX-files) available in a
0100 %   MATLAB(R) or comparable environment containing parts covered
0101 %   under other licensing terms, the licensors of MATPOWER grant
0102 %   you additional permission to convey the resulting work.
0103 
0104 if isstruct(bus)
0105     mpc = bus;
0106     if nargin == 1
0107         first = ~isfield(mpc, 'order');
0108         if first || mpc.order.state == 'e'
0109             %% define names for columns to data matrices
0110             [PQ, PV, REF, NONE, BUS_I, BUS_TYPE] = idx_bus;
0111             [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS] = idx_gen;
0112             [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0113                 TAP, SHIFT, BR_STATUS] = idx_brch;
0114             [AREA_I, PRICE_REF_BUS] = idx_area;
0115 
0116             %% initialize order
0117             if first
0118                 status = struct('on',   [], ...
0119                                 'off',  []  );
0120                 tmp = struct( ...
0121                         'e2i',      [], ...
0122                         'i2e',      [], ...
0123                         'status',   status ...
0124                     );
0125                 o = struct( ...
0126                         'ext',      struct( ...
0127                                 'bus',      [], ...
0128                                 'branch',   [], ...
0129                                 'gen',      [] ...
0130                             ), ...
0131                         'bus',      tmp, ...
0132                         'gen',      tmp, ...
0133                         'branch',   struct('status', status) ...
0134                     );
0135             else
0136                 o = mpc.order;
0137             end
0138 
0139             %% sizes
0140             nb = size(mpc.bus, 1);
0141             ng = size(mpc.gen, 1);
0142             ng0 = ng;
0143             if isfield(mpc, 'A') && size(mpc.A, 2) < 2*nb + 2*ng
0144                 dc = 1;
0145             elseif isfield(mpc, 'N') && size(mpc.N, 2) < 2*nb + 2*ng
0146                 dc = 1;
0147             else
0148                 dc = 0;
0149             end
0150 
0151             %% save data matrices with external ordering
0152             o.ext.bus    = mpc.bus;
0153             o.ext.branch = mpc.branch;
0154             o.ext.gen    = mpc.gen;
0155             if isfield(mpc, 'areas')
0156                 if isempty(mpc.areas)           %% if areas field is empty
0157                     mpc = rmfield(mpc, 'areas');    %% delete it (so it gets ignored)
0158                 else                            %% otherwise
0159                     o.ext.areas = mpc.areas;        %% save it
0160                 end
0161             end
0162 
0163             %% check that all buses have a valid BUS_TYPE
0164             bt = mpc.bus(:, BUS_TYPE);
0165             err = find(~(bt == PQ | bt == PV | bt == REF | bt == NONE));
0166             if ~isempty(err)
0167                 error('ext2int: bus %d has an invalid BUS_TYPE', err);
0168             end
0169 
0170             %% determine which buses, branches, gens are connected & in-service
0171             n2i = sparse(mpc.bus(:, BUS_I), ones(nb, 1), 1:nb, max(mpc.bus(:, BUS_I)), 1);
0172             bs = (bt ~= NONE);                      %% bus status
0173             o.bus.status.on     = find(  bs );      %% connected
0174             o.bus.status.off    = find( ~bs );      %% isolated
0175             gs = ( mpc.gen(:, GEN_STATUS) > 0 & ... %% gen status
0176                     bs(n2i(mpc.gen(:, GEN_BUS))) );
0177             o.gen.status.on     = find(  gs );      %% on and connected
0178             o.gen.status.off    = find( ~gs );      %% off or isolated
0179             brs = ( mpc.branch(:, BR_STATUS) & ...  %% branch status
0180                     bs(n2i(mpc.branch(:, F_BUS))) & ...
0181                     bs(n2i(mpc.branch(:, T_BUS))) );
0182             o.branch.status.on  = find(  brs );     %% on and connected
0183             o.branch.status.off = find( ~brs );
0184             if isfield(mpc, 'areas')
0185                 as = bs(n2i(mpc.areas(:, PRICE_REF_BUS)));
0186                 o.areas.status.on   = find(  as );
0187                 o.areas.status.off  = find( ~as );
0188             end
0189 
0190             %% delete stuff that is "out"
0191             if ~isempty(o.bus.status.off)
0192                 mpc.bus(o.bus.status.off, :) = [];
0193             end
0194             if ~isempty(o.branch.status.off)
0195                 mpc.branch(o.branch.status.off, :) = [];
0196             end
0197             if ~isempty(o.gen.status.off)
0198                 mpc.gen(o.gen.status.off, :) = [];
0199             end
0200             if isfield(mpc, 'areas') && ~isempty(o.areas.status.off)
0201                 mpc.areas(o.areas.status.off, :) = [];
0202             end
0203 
0204             %% update size
0205             nb = size(mpc.bus, 1);
0206 
0207             %% apply consecutive bus numbering
0208             o.bus.i2e = mpc.bus(:, BUS_I);
0209             o.bus.e2i = sparse(max(o.bus.i2e), 1);
0210             o.bus.e2i(o.bus.i2e) = (1:nb)';
0211             mpc.bus(:, BUS_I)       = o.bus.e2i( mpc.bus(:, BUS_I)      );
0212             mpc.gen(:, GEN_BUS)     = o.bus.e2i( mpc.gen(:, GEN_BUS)    );
0213             mpc.branch(:, F_BUS)    = o.bus.e2i( mpc.branch(:, F_BUS)   );
0214             mpc.branch(:, T_BUS)    = o.bus.e2i( mpc.branch(:, T_BUS)   );
0215             if isfield(mpc, 'areas')
0216                 mpc.areas(:, PRICE_REF_BUS) = o.bus.e2i( mpc.areas(:, PRICE_REF_BUS)  );
0217             end
0218 
0219             %% reorder gens in order of increasing bus number
0220             [tmp, o.gen.e2i] = sort(mpc.gen(:, GEN_BUS));
0221             [tmp, o.gen.i2e] = sort(o.gen.e2i);
0222             mpc.gen = mpc.gen(o.gen.e2i, :);
0223 
0224             if isfield(o, 'int')
0225                 o = rmfield(o, 'int');
0226             end
0227             o.state = 'i';
0228             mpc.order = o;
0229 
0230             %% update gencost, A and N
0231             if isfield(mpc, 'gencost')
0232                 ordering = {'gen'};         %% Pg cost only
0233                 if size(mpc.gencost, 1) == 2*ng0
0234                     ordering{2} = 'gen';    %% include Qg cost
0235                 end
0236                 mpc = e2i_field(mpc, 'gencost', ordering);
0237             end
0238             if isfield(mpc, 'A') || isfield(mpc, 'N')
0239                 if dc
0240                     ordering = {'bus', 'gen'};
0241                 else
0242                     ordering = {'bus', 'bus', 'gen', 'gen'};
0243                 end
0244             end
0245             if isfield(mpc, 'A')
0246                 mpc = e2i_field(mpc, 'A', ordering, 2);
0247             end
0248             if isfield(mpc, 'N')
0249                 mpc = e2i_field(mpc, 'N', ordering, 2);
0250             end
0251 
0252             %% execute userfcn callbacks for 'ext2int' stage
0253             if isfield(mpc, 'userfcn')
0254                 mpc = run_userfcn(mpc.userfcn, 'ext2int', mpc);
0255             end
0256         end
0257 
0258         i2e = mpc;
0259     else                    %% convert extra data
0260         ordering = branch;              %% rename argument
0261         if nargin < 4
0262             dim = 1;
0263         else
0264             dim = areas;                %% rename argument
0265         end
0266         if ischar(gen) || iscell(gen)   %% field
0267             warning('Calls of the form MPC = EXT2INT(MPC, ''FIELD_NAME'', ...) have been deprecated. Please replace EXT2INT with E2I_FIELD.');
0268             i2e = e2i_field(mpc, gen, branch, dim);
0269         else                            %% value
0270             warning('Calls of the form VAL = EXT2INT(MPC, VAL, ...) have been deprecated. Please replace EXT2INT with E2I_DATA.');
0271             i2e = e2i_data(mpc, gen, branch, dim);
0272         end
0273     end
0274 else            %% old form
0275     %% define names for columns to data matrices
0276     [PQ, PV, REF, NONE, BUS_I] = idx_bus;
0277     [GEN_BUS] = idx_gen;
0278     [F_BUS, T_BUS] = idx_brch;
0279     [AREA_I, PRICE_REF_BUS] = idx_area;
0280 
0281     %% create map of external bus numbers to bus indices
0282     i2e = bus(:, BUS_I);
0283     e2i = sparse(max(i2e), 1);
0284     e2i(i2e) = (1:size(bus, 1))';
0285 
0286     %% renumber buses consecutively
0287     bus(:, BUS_I)               = e2i( bus(:, BUS_I)            );
0288     gen(:, GEN_BUS)             = e2i( gen(:, GEN_BUS)          );
0289     branch(:, F_BUS)            = e2i( branch(:, F_BUS)         );
0290     branch(:, T_BUS)            = e2i( branch(:, T_BUS)         );
0291     if nargin > 3 && nargout > 4 && ~isempty(areas)
0292         areas(:, PRICE_REF_BUS) = e2i( areas(:, PRICE_REF_BUS)  );
0293     end
0294 end

Generated on Mon 26-Jan-2015 15:00:13 by m2html © 2005