![]() |
IA_CoMP
Interference Alignment and Coordinated Multipoint
|
00001 // Copyright 2011-2013, Per Zetterberg, KTH Royal Institute of Technology 00002 // This program is free software: you can redistribute it and/or modify 00003 // it under the terms of the GNU General Public License as published by 00004 // the Free Software Foundation, either version 3 of the License, or 00005 // (at your option) any later version. 00006 // 00007 // This program is distributed in the hope that it will be useful, 00008 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 // GNU General Public License for more details. 00011 // 00012 // You should have received a copy of the GNU General Public License 00013 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00014 // 00015 00016 #include "IA2_node.hpp" 00017 #include <itpp/itcomm.h> 00018 #include <itpp/stat/misc_stat.h> 00019 00020 void IA2_node::calculate_beamformers(void) { 00021 00022 // Perform the distrinuted IA algo found in "Approaching the Capacity 00023 // of Wireless Networks through Distributed Interference 00024 // Alignment", by Krishna Gomadam, Viveck R. Cadambe and 00025 // Syed A. Jafar. IEEE Globecom 2008 and ArXiv http://arxiv.org/abs/0803.3816. 00026 // The ArXiv version is most detailed. 00027 00028 // If max_SINR=true (see below) then the Max-SNIR version is used. 00029 00030 /* The matrix Vbig[i1](:,:) contains, as it's i2:th column, the 00031 precoder for stream i1 on the ix_all(i2) subcarrier. 00032 The vector ix_all contains all the subcarrier which 00033 are used (not all are). 00034 The subcarrier numbers we use are actually 00035 1,...,ai[0].rightmost_carrier 00036 and ai[0].leftmost_carrier to Nfft-1. These are the ones 00037 closest to the 0Hz unused DC subcarrier. 00038 Note that subcarrier numbers greater than Nfft/2 wraps 00039 into the negative part of the spectrum. 00040 The two carriers ix_all(ai[0].pilot_carrier1_sub) and 00041 ix_all(ai[0].pilot_carrier2_sub) 00042 are in the middle of the positive and negative part of the 00043 spectrum, respectively. The names indicate that there would be only 00044 pilots being transmitted on these subcarriers. However, this is 00045 not the case. Since we have set "do_use_pilot_carriers=false". 00046 00047 Note that the paper by Gadambe&Jafar referenced above 00048 is defined for a single carrier. We use the fact that we 00049 have multiple subcarriers to speed up convergence, 00050 The idea is that adjacent subcarriers should have similiar 00051 channel responses and thus we use the adjacent subcarrier 00052 as the starting point for the iteration. 00053 */ 00054 00055 /* Define a matrix to store all the beamformers on a singe subcarrier */ 00056 cmat v_old(num_ant_bs,num_streams); 00057 00058 /* Initialize v_old at the beamformers we used in previous time-slot 00059 on the carrier pilot_carrier1_sub. */ 00060 for (uint32_t i1=0;i1<num_streams;i1++) { 00061 for (uint32_t i3=0;i3<num_ant_bs;i3++) { 00062 v_old(i3,i1)=Vbig[i1](i3,ai[0].pilot_carrier1_sub); 00063 }; 00064 }; 00065 00066 /* Update the beamformers starting from subcarrier index 00067 ix_all(ai[0].pilot_carrier1_sub) and ending at 00068 ix_all(ai[0].rightmost_carrier_sub) */ 00069 iteration(v_old,ai[0].pilot_carrier1_sub,ai[0].rightmost_carrier_sub,1); 00070 /* Update the beamformers starting from subcarrier index 00071 ix_all(ai[0].pilot_carrier1_sub) and ending at ix_all(0) */ 00072 iteration(v_old,ai[0].pilot_carrier1_sub,0,-1); 00073 00074 00075 /* Initialize v_old at the beamformers we used in previous time-slot 00076 on the carrier pilot_carrier1_sub. */ 00077 for (uint32_t i1=0;i1<num_streams;i1++) { 00078 for (uint32_t i3=0;i3<num_ant_bs;i3++) { 00079 v_old(i3,i1)=Vbig[i1](i3,ai[0].pilot_carrier2_sub); 00080 }; 00081 }; 00082 00083 /* Update the beamformers starting from subcarrier index 00084 ix_all(ai[0].pilot_carrier2_sub) and ending at ix_all(length_ix_all-1) 00085 i.e. the maximum used subcarrier number.*/ 00086 iteration(v_old,ai[0].pilot_carrier2_sub,ai[0].length_ix_all-1,1); 00087 00088 /* Update the beamformers starting from subcarrier index 00089 ix_all(ai[0].pilot_carrier2_sub) and ending at ix_all(length_ix_all-1) 00090 i.e. the maximum used subcarrier number.*/ 00091 iteration(v_old,ai[0].pilot_carrier2_sub,ai[0].leftmost_carrier_sub,-1); 00092 00093 00094 00095 }; 00096 00097 void IA2_node::iteration(const cmat v_old_in,int subcarrier_ix_start,int subcarrier_ix_stop,int increment) { 00098 00099 cmat B(num_ant_ms,num_ant_ms); // Interference plus noise covariance matrix 00100 cmat Hi(num_ant_ms,num_ant_bs); // Intermediate channel matrix 00101 cmat Br(num_ant_bs,num_ant_bs); // Reverse interference plus noise matrix 00102 cmat v_old; 00103 00104 cvec v(num_ant_bs); // Intermediate precoding vector 00105 cvec u(num_ant_ms); // Intermediate receiving vector 00106 cvec h(num_ant_ms); // Intermediate kind of channel vector 00107 cvec hr(num_ant_bs); // Intermediate kind of channel vector 00108 complex<double> noise_variance; 00109 cmat u_old(num_ant_ms,num_ms); 00110 noise_variance=5901.6; 00111 ivec bs_antenna_ix_for_ms_ix[3]; 00112 bool max_SINR=true; 00113 cmat E, Er; 00114 vec d, dr; 00115 vec SINR(3); 00116 vec SINR_min="1e10 1e10 1e10"; 00117 00118 v_old=v_old_in; 00119 00120 if (!max_SINR) { 00121 E.set_size(num_ant_ms,num_ant_ms); 00122 Er.set_size(num_ant_bs,num_ant_bs); 00123 d.set_length(num_ant_ms); 00124 dr.set_length(num_ant_bs); 00125 }; 00126 00127 if (scenario==1) { // IA 00128 // The indecies of the base-station antennas, numbered from 0 to 5, 00129 // used by MS 0,1 and 2 in the IA approach. 00130 bs_antenna_ix_for_ms_ix[0]="0 1"; 00131 bs_antenna_ix_for_ms_ix[1]="2 3"; 00132 bs_antenna_ix_for_ms_ix[2]="4 5"; 00133 }; 00134 if (scenario==2) { // COMP 00135 // The indecies of the base-station antennas, numbered from 0 to 5, 00136 // used by MS 0,1 and 2 in the CoMP approach. 00137 bs_antenna_ix_for_ms_ix[0]="0 1 2 3 4 5"; 00138 bs_antenna_ix_for_ms_ix[1]="0 1 2 3 4 5"; 00139 bs_antenna_ix_for_ms_ix[2]="0 1 2 3 4 5"; 00140 } 00141 00142 for (int ix=subcarrier_ix_start; 00143 ix!=subcarrier_ix_stop+increment;ix+=increment) { 00144 00145 for (int iter=0;iter<10;iter++) { 00146 00147 /* Calculate all receive combiners */ 00148 for (uint32_t i1=0;i1<num_streams;i1++) { 00149 00150 /* B is going to be the noise+interference covariance matrix 00151 for MS i1. Start with the noise. */ 00152 eye(num_ant_ms,B); 00153 B=B*noise_variance; 00154 00155 for (uint32_t i2=0;i2<num_streams;i2++) { 00156 00157 00158 //cout << "================= \n"; 00159 //cout << "v_old=" << v_old << endl; 00160 00161 /* v is the pre-coder of stream i2 */ 00162 v=v_old.get_col(i2); 00163 if (!(i1==i2)) { 00164 00165 00166 // Fill Hi with the MIMO channel from interfering stream i2 00167 // from the viewpoint of stream (i.e. MS) i1. 00168 00169 for (uint32_t i3=0;i3<num_ant_bs;i3++) { 00170 for (uint32_t i4=0;i4<num_ant_ms;i4++) { 00171 00172 Hi(i4,i3)=H[stream_ix_to_ms_ix(i1)][bs_antenna_ix_for_ms_ix[i2](i3)](i4,ix); 00173 }; 00174 }; 00175 00176 // h is the vector channel given that stream i2 use pre-coder v. 00177 h=Hi*v; 00178 00179 /* B is the total downlink interference covariance matrix for i1*/ 00180 B=B+outer_product(h,h,true); 00181 }; 00182 //cout << "B=" << B << ";" << endl; 00183 00184 }; 00185 00186 if (max_SINR) { 00187 00188 /* v is now the pre-coder of the desired stream */ 00189 v=v_old.get_col(i1); 00190 /* Fill Hi with MIMO channel of the desired stream */ 00191 for (uint32_t i3=0;i3<num_ant_bs;i3++) { 00192 for (uint32_t i4=0;i4<num_ant_ms;i4++) { 00193 Hi(i4,i3)=H[stream_ix_to_ms_ix(i1)][bs_antenna_ix_for_ms_ix[i1](i3)](i4,ix); 00194 }; 00195 }; 00196 /* Calculate MSSE */ 00197 h=Hi*v; 00198 u=inv(B)*h; 00199 u=u/norm(u,2); 00200 u_old.set_col(i1,u); 00201 00202 //cout << "Hd=" << Hi << ";" << endl; 00203 //cout << "u=" << u << ";" << endl; 00204 00205 } 00206 else 00207 { 00208 eig_sym(B,d,E); 00209 u=E.get_col(0); 00210 u_old.set_col(i1,u); 00211 }; 00212 /* Calculate the SINR given everything is perfect */ 00213 SINR(i1)=abs(dot(conj(u),h)); 00214 SINR(i1)=SINR(i1)*SINR(i1)/abs((dot(conj(u),B*u))); 00215 }; 00216 00217 00218 00219 /* Calcute new downlink beamformers */ 00220 for (uint32_t i1=0;i1<num_streams;i1++) { 00221 00222 /* Br is the reciprocal interference plus noise covariance matrix */ 00223 eye(num_ant_bs,Br); 00224 Br=Br*noise_variance; 00225 for (uint32_t i2=0;i2<num_streams;i2++) { 00226 if (i1!=i2) { 00227 /* u is receiver filter of stream i2 - now acting as transmitter */ 00228 u=u_old.get_col(i2); 00229 /* Hi is the reciprocal MIMO channel from MS i2 to BS i1 */ 00230 for (uint32_t i3=0;i3<num_ant_bs;i3++) { 00231 for (uint32_t i4=0;i4<num_ant_ms;i4++) { 00232 Hi(i4,i3)=H[stream_ix_to_ms_ix(i2)][bs_antenna_ix_for_ms_ix[i1](i3)](i4,ix); 00233 }; 00234 }; 00235 00236 /* Reciprocal vector channel with u as transmitter */ 00237 hr=hermitian_transpose(Hi)*u; 00238 Br=Br+outer_product(hr,hr,true); 00239 }; 00240 }; 00241 if (max_SINR) { 00242 /* u is the reciprocal beamformer of stream i1 */ 00243 u=u_old.get_col(i1); 00244 /* Hi is the desired reciprocal channel of stream i1 */ 00245 for (uint32_t i3=0;i3<num_ant_bs;i3++) { 00246 for (uint32_t i4=0;i4<num_ant_ms;i4++) { 00247 Hi(i4,i3)=H[stream_ix_to_ms_ix(i1)][bs_antenna_ix_for_ms_ix[i1](i3)](i4,ix); 00248 }; 00249 }; 00250 00251 /* Calculate new reciprocal beamformer */ 00252 hr=hermitian_transpose(Hi)*u; 00253 v=inv(Br)*hr; 00254 v=v/norm(v,2); 00255 Vbig[i1].set_col(ix,v); 00256 v_old.set_col(i1,v); 00257 00258 //cout << "Hd=" << Hi << ";" << endl; 00259 //cout << "v=" << v_old << ";" << endl; 00260 } 00261 else 00262 { 00263 eig_sym(Br,dr,Er); 00264 v=Er.get_col(0); 00265 Vbig[i1].set_col(ix,v); 00266 v_old.set_col(i1,v); 00267 }; 00268 }; 00269 }; 00270 for (uint32_t i1=0;i1<num_ms;i1++) { 00271 // Stor the worst SNIR of stream 0,1,2 in SINR_min 00272 // (worst over subcarriers). 00273 if (SINR(i1)<SINR_min(i1)) 00274 SINR_min(i1)=SINR(i1); 00275 }; 00276 }; 00277 //cout << "SINR_min=" << SINR_min << endl; 00278 };