MAT2VEC Converts a SDP matrix into a a list form used in the matrix completion decomposition. [SDPVEC] = MAT2VEC(SDPMAT, WREF_DD, WREF_QQ, WREF_DQ, MATIDX_DD,MATIDX_QQ, MATIDX_DQ) Used in the formation of the matrix completion decomposition for the semidefinite programming relaxation of the optimal power flow. Converts a 2*nbus by 2*nbus symmetric matrix sdpmat into a list form. For each nonzero element of sdpmat, the list form in sdpvec gives the appropriate matrix, the location in the matrix, and the value for that element. Inputs: SDPMAT : Symmetric 2*nbus by 2*nbus matrix (intended to be Yk, Yk_, Mk, Ylineft, Ylinetf, Y_lineft, Y_linetf from the semidefinite programming relaxation). WREF_DD : Matrix with three columns. The first column is a numbering 1:size(Wref_dd,1). The second and third columns indicate the row and column indices of the elements of the matrix sdpmat, with the row of Wref_dd corresponding to the index of matidx_dd. That is, the element of sdpmat located in row Wref_dd(i,1), column Wref_dd(i,2) corresponds to matidx_dd(i). WREF_QQ : Similar to Wref_dd, except for the qq entries of sdpmat. WREF_DQ : Similar to Wref_dd, except for the dq entries of sdpmat. MATIDX_DD : Matrix with three columns. Row i of matidx_dd indicates the location of sdpmat(Wref_dd(i,1), Wref_dd(i,2)). The first column indicates the index of the corresponding matrix. The second and third columns indicate the row and column, respectively, of the corresponding matrix. MATIDX_QQ : Similar to matidx_dd, except corresponding to the qq entries of sdpmat. MATIDX_DQ : Similar to matidx_dd, except corresponding to the dq entries of sdpmat. Outputs: SDPVEC : A matrix with four columns, with a row for each nonzero element of sdpmat. The first column gives the index of the decomposed matrix. The second and third columns give the row and column, respectively, of the appropriate entry of the decomposed matrix. The fourth column is the value of the entry.
0001 function [sdpvec]=mat2vec(sdpmat, Wref_dd, Wref_qq, Wref_dq, matidx_dd, matidx_qq, matidx_dq) 0002 %MAT2VEC Converts a SDP matrix into a a list form used in the matrix 0003 %completion decomposition. 0004 % [SDPVEC] = MAT2VEC(SDPMAT, WREF_DD, WREF_QQ, WREF_DQ, MATIDX_DD,MATIDX_QQ, MATIDX_DQ) 0005 % 0006 % Used in the formation of the matrix completion decomposition for the 0007 % semidefinite programming relaxation of the optimal power flow. Converts 0008 % a 2*nbus by 2*nbus symmetric matrix sdpmat into a list form. For each 0009 % nonzero element of sdpmat, the list form in sdpvec gives the 0010 % appropriate matrix, the location in the matrix, and the value for that 0011 % element. 0012 % 0013 % Inputs: 0014 % SDPMAT : Symmetric 2*nbus by 2*nbus matrix (intended to be Yk, Yk_, 0015 % Mk, Ylineft, Ylinetf, Y_lineft, Y_linetf from the semidefinite 0016 % programming relaxation). 0017 % WREF_DD : Matrix with three columns. The first column is a 0018 % numbering 1:size(Wref_dd,1). The second and third columns 0019 % indicate the row and column indices of the elements of the 0020 % matrix sdpmat, with the row of Wref_dd corresponding to the 0021 % index of matidx_dd. That is, the element of sdpmat located in 0022 % row Wref_dd(i,1), column Wref_dd(i,2) corresponds to 0023 % matidx_dd(i). 0024 % WREF_QQ : Similar to Wref_dd, except for the qq entries of sdpmat. 0025 % WREF_DQ : Similar to Wref_dd, except for the dq entries of sdpmat. 0026 % MATIDX_DD : Matrix with three columns. Row i of matidx_dd indicates 0027 % the location of sdpmat(Wref_dd(i,1), Wref_dd(i,2)). The first 0028 % column indicates the index of the corresponding matrix. The 0029 % second and third columns indicate the row and column, 0030 % respectively, of the corresponding matrix. 0031 % MATIDX_QQ : Similar to matidx_dd, except corresponding to the qq 0032 % entries of sdpmat. 0033 % MATIDX_DQ : Similar to matidx_dd, except corresponding to the dq 0034 % entries of sdpmat. 0035 % 0036 % Outputs: 0037 % SDPVEC : A matrix with four columns, with a row for each nonzero 0038 % element of sdpmat. The first column gives the index of the 0039 % decomposed matrix. The second and third columns give the row 0040 % and column, respectively, of the appropriate entry of the 0041 % decomposed matrix. The fourth column is the value of the entry. 0042 0043 % MATPOWER 0044 % Copyright (c) 2013-2019, Power Systems Engineering Research Center (PSERC) 0045 % by Daniel Molzahn, PSERC U of Wisc, Madison 0046 % 0047 % This file is part of MATPOWER/mx-sdp_pf. 0048 % Covered by the 3-clause BSD License (see LICENSE file for details). 0049 % See https://github.com/MATPOWER/mx-sdp_pf/ for more info. 0050 0051 %% Setup 0052 0053 nbus = size(sdpmat,1) / 2; 0054 [matrow, matcol, matval] = find(triu(sdpmat)); 0055 0056 % To speed up this function, rather than search throuh the entire Wref_dd, 0057 % Wref_qq, Wref_dq vectors every time we look up a nonzero entry of sdpmat, 0058 % filter out the entries that will actually be used in the rest of the 0059 % function. 0060 0061 dd_buses = unique([matrow(matrow <= nbus); matcol(matcol <= nbus)]); 0062 dd_rows = []; 0063 for i=1:length(dd_buses) 0064 dd_rows = [dd_rows; find(Wref_dd(:,2) == dd_buses(i) | Wref_dd(:,3) == dd_buses(i))]; 0065 end 0066 Wref_dd = Wref_dd(dd_rows,:); 0067 0068 qq_buses = unique([matrow(matrow > nbus); matcol(matcol > nbus)]) - nbus; 0069 qq_rows = []; 0070 for i=1:length(qq_buses) 0071 qq_rows = [qq_rows; find(Wref_qq(:,2) == qq_buses(i) | Wref_qq(:,3) == qq_buses(i))]; 0072 end 0073 Wref_qq = Wref_qq(qq_rows,:); 0074 0075 dq_buses = unique([matrow(matrow > nbus)-nbus; matcol(matcol > nbus)-nbus; matrow(matrow <= nbus); matcol(matcol <= nbus)]); 0076 dq_rows = []; 0077 for i=1:length(dq_buses) 0078 dq_rows = [dq_rows; find(Wref_dq(:,2) == dq_buses(i) | Wref_dq(:,3) == dq_buses(i))]; 0079 end 0080 Wref_dq = Wref_dq(dq_rows,:); 0081 0082 0083 %% Form sdpvec 0084 0085 sdpvec = zeros(2*length(matrow),4); 0086 idx = 0; 0087 for m = 1:length(matrow); 0088 idx = idx + 1; 0089 if matrow(m) <= nbus && matcol(m) <= nbus % In the dd section of the W matrix 0090 Wref_dd_row = find( (Wref_dd(:,2) == matrow(m) & Wref_dd(:,3) == matcol(m)) | ... 0091 (Wref_dd(:,3) == matrow(m) & Wref_dd(:,2) == matcol(m)), 1); 0092 sdpvec(idx,:) = [matidx_dd(Wref_dd(Wref_dd_row,1),1) matidx_dd(Wref_dd(Wref_dd_row,1),2) matidx_dd(Wref_dd(Wref_dd_row,1),3) matval(m)]; 0093 idx = idx + 1; 0094 sdpvec(idx,:) = [matidx_dd(Wref_dd(Wref_dd_row,1),1) matidx_dd(Wref_dd(Wref_dd_row,1),3) matidx_dd(Wref_dd(Wref_dd_row,1),2) matval(m)]; 0095 elseif matrow(m) > nbus && matcol(m) > nbus % In the qq section of the W matrix 0096 Wref_qq_row = find( (Wref_qq(:,2) == (matrow(m)-nbus) & Wref_qq(:,3) == (matcol(m))-nbus) | ... 0097 (Wref_qq(:,3) == (matrow(m)-nbus) & Wref_qq(:,2) == (matcol(m)-nbus)), 1); 0098 sdpvec(idx,:) = [matidx_qq(Wref_qq(Wref_qq_row,1),1) matidx_qq(Wref_qq(Wref_qq_row,1),2) matidx_qq(Wref_qq(Wref_qq_row,1),3) matval(m)]; 0099 idx = idx + 1; 0100 sdpvec(idx,:) = [matidx_qq(Wref_qq(Wref_qq_row,1),1) matidx_qq(Wref_qq(Wref_qq_row,1),3) matidx_qq(Wref_qq(Wref_qq_row,1),2) matval(m)]; 0101 elseif (matrow(m) > nbus && matcol(m) <= nbus) % In the dq section of the W matrix 0102 Wref_dq_row = find(Wref_dq(:,3) == (matrow(m)-nbus) & Wref_dq(:,2) == matcol(m), 1); 0103 0104 sdpvec(idx,:) = [matidx_dq(Wref_dq(Wref_dq_row,1),1) matidx_dq(Wref_dq(Wref_dq_row,1),2) matidx_dq(Wref_dq(Wref_dq_row,1),3) matval(m)]; 0105 idx = idx + 1; 0106 sdpvec(idx,:) = [matidx_dq(Wref_dq(Wref_dq_row,1),1) matidx_dq(Wref_dq(Wref_dq_row,1),3) matidx_dq(Wref_dq(Wref_dq_row,1),2) matval(m)]; 0107 elseif (matrow(m) <= nbus && matcol(m) > nbus) % In the dq section of the W matrix 0108 Wref_dq_row = find(Wref_dq(:,2) == matrow(m) & Wref_dq(:,3) == (matcol(m)-nbus), 1); 0109 0110 sdpvec(idx,:) = [matidx_dq(Wref_dq(Wref_dq_row,1),1) matidx_dq(Wref_dq(Wref_dq_row,1),2) matidx_dq(Wref_dq(Wref_dq_row,1),3) matval(m)]; 0111 idx = idx + 1; 0112 sdpvec(idx,:) = [matidx_dq(Wref_dq(Wref_dq_row,1),1) matidx_dq(Wref_dq(Wref_dq_row,1),3) matidx_dq(Wref_dq(Wref_dq_row,1),2) matval(m)]; 0113 else 0114 error('mat2vec: Invalid matrow or matcol for bus %i',k); 0115 end 0116 end 0117 0118 sdpvec = unique(sdpvec,'rows'); % Don't double count diagonals