00001 00029 #include <itpp/comm/stc.h> 00030 00031 namespace itpp 00032 { 00033 00034 void STC::Hassibi_block_code(void) 00035 /* this function implements the A and B matrices needed for Space-Time block codes generation following the Hassibi's approach: 00036 * S = sum_{q=1}^symb_block (A_q alpha_q + jB_q beta_q), 00037 * where s_q = alpha_q+jbeta_q is the symbol after modulation 00038 * each A_q and B_q matrix has dimension TxM 00039 * different A_q and B_q matrices are stacked one below the other, e.g. [A_1;A_2;...;A_Q] 00040 00041 * input: code_name - code name whose generator matrices are to be generated 00042 * const_size - constellation size (used in Damen code) 00043 * ouputs: symb_block - number of symbols per block 00044 * A, B - generator matrices 00045 * inputs/ouputs: for some codes these are inputs for others they are 00046 * predefined, so they are outputs only 00047 * em_antennas - number of emission antenna 00048 * channel_uses - channel uses 00049 */ 00050 { 00051 if (code_name=="V-BLAST_MxN")//classical V-BLAST 00052 { 00053 symb_block = channel_uses*em_antennas;//number of symbols/block 00054 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameter is predefined:" << std::endl; 00055 std::cout << "symb_block = channel_uses*em_antennas = " << symb_block << std::endl; 00056 A.set_size(symb_block*channel_uses, em_antennas); 00057 A.zeros(); 00058 itpp::mat temp(channel_uses, em_antennas); 00059 temp.zeros(); 00060 register int tau,m; 00061 for (tau=0; tau<channel_uses; tau++) 00062 { 00063 for (m=0; m<em_antennas; m++) 00064 { 00065 temp(tau,m) = 1; 00066 A.set_submatrix((em_antennas*(tau-1)+m-1), 0, to_cmat(temp)); 00067 temp(tau,m) = 0; 00068 } 00069 } 00070 B = A; 00071 } 00072 else if (code_name=="imp_V-BLAST_MxN")//improved V-BLAST (code (31) in Hassibi's paper) 00073 { 00074 if (channel_uses!=em_antennas) 00075 { 00076 std::cout << "STC::LDcode: Warning! For " << code_name << " channel_uses and em_antennas must be equal. Choosing channel_uses=em_antennas" << std::endl; 00077 channel_uses = em_antennas; 00078 } 00079 symb_block = channel_uses*em_antennas;//number of symbols/block 00080 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameter is predefined:" << std::endl; 00081 std::cout << "symb_block = " << symb_block << std::endl; 00082 std::complex<double> j(0,1); 00083 itpp::cmat D = itpp::diag(exp(j*(2*itpp::pi/em_antennas)*itpp::linspace(0, em_antennas-1, em_antennas))); 00084 itpp::mat P = itpp::diag(itpp::ones(em_antennas-1), -1); 00085 P(0,em_antennas-1) = 1; 00086 A.set_size(symb_block*channel_uses, em_antennas); 00087 A.zeros(); 00088 register int k,l; 00089 for (k=0; k<channel_uses; k++) 00090 for (l=0; l<em_antennas; l++) 00091 A.set_submatrix((em_antennas*k+l)*channel_uses, 0, diag_pow(D, k)*itpp::to_cmat(mat_pow(P, l))/std::sqrt(double(em_antennas))); 00092 B = A; 00093 } 00094 else if (code_name=="Alamouti_2xN")//Alamouti's orthogonal code 00095 { 00096 em_antennas = 2;//emission antenna 00097 channel_uses = 2;//channel uses 00098 symb_block = 2;//number of symbols/block 00099 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00100 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00101 A = "1 0;\ 00102 0 1;\ 00103 0 1;\ 00104 -1 0";//A_1; A_2 00105 B = "1 0;\ 00106 0 -1;\ 00107 0 1;\ 00108 1 0";//B_1; B_2 00109 } 00110 else if (code_name=="Switched_Alamouti_4xN") 00111 { 00112 em_antennas = 4;//emission antenna 00113 channel_uses = 4;//channel uses 00114 symb_block = 4;//number of symbols/block 00115 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00116 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00117 A = "1 0 0 0;\ 00118 0 1 0 0;\ 00119 0 0 0 0;\ 00120 0 0 0 0;\ 00121 0 1 0 0;\ 00122 -1 0 0 0;\ 00123 0 0 0 0;\ 00124 0 0 0 0;\ 00125 0 0 0 0;\ 00126 0 0 0 0;\ 00127 0 0 1 0;\ 00128 0 0 0 1;\ 00129 0 0 0 0;\ 00130 0 0 0 0;\ 00131 0 0 0 1;\ 00132 0 0 -1 0";//A_1; A_2; A_3; A_4 00133 A *= std::sqrt(2.0);//normalization 00134 B = "1 0 0 0;\ 00135 0 -1 0 0;\ 00136 0 0 0 0;\ 00137 0 0 0 0;\ 00138 0 1 0 0;\ 00139 1 0 0 0;\ 00140 0 0 0 0;\ 00141 0 0 0 0;\ 00142 0 0 0 0;\ 00143 0 0 0 0;\ 00144 0 0 1 0;\ 00145 0 0 0 -1;\ 00146 0 0 0 0;\ 00147 0 0 0 0;\ 00148 0 0 0 1;\ 00149 0 0 1 0";//B_1; B_2; B_3; B_4 00150 B *= std::sqrt(2.0); 00151 } 00152 else if (code_name=="Double_Alamouti_4xN") 00153 { 00154 em_antennas = 4;//emission antenna 00155 channel_uses = 2;//channel uses 00156 symb_block = 4;//number of symbols/block 00157 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00158 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00159 A = "1 0 0 0;\ 00160 0 1 0 0;\ 00161 0 0 1 0;\ 00162 0 0 0 1;\ 00163 0 1 0 0;\ 00164 -1 0 0 0;\ 00165 0 0 0 1;\ 00166 0 0 -1 0";//A_1; A_2; A_3; A_4 00167 B = "1 0 0 0;\ 00168 0 -1 0 0;\ 00169 0 0 1 0;\ 00170 0 0 0 -1;\ 00171 0 1 0 0;\ 00172 1 0 0 0;\ 00173 0 0 0 1;\ 00174 0 0 1 0";//B_1; B_2; B_3; B_4 00175 } 00176 else if (code_name=="Jafarkhani_4xN")//Jafarkhani's quasi-orthogonal code 00177 { 00178 em_antennas = 4;//emission antenna 00179 channel_uses = 4;//channel uses 00180 symb_block = 4;//number of symbols/block 00181 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00182 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00183 A = "1 0 0 0;\ 00184 0 1 0 0;\ 00185 0 0 1 0;\ 00186 0 0 0 1;\ 00187 0 1 0 0;\ 00188 -1 0 0 0;\ 00189 0 0 0 1;\ 00190 0 0 -1 0;\ 00191 0 0 1 0;\ 00192 0 0 0 1;\ 00193 -1 0 0 0;\ 00194 0 -1 0 0;\ 00195 0 0 0 1;\ 00196 0 0 -1 0;\ 00197 0 -1 0 0;\ 00198 1 0 0 0";//A_1; A_2; A_3; A_4 00199 B = "1 0 0 0;\ 00200 0 -1 0 0;\ 00201 0 0 -1 0;\ 00202 0 0 0 1;\ 00203 0 1 0 0;\ 00204 1 0 0 0;\ 00205 0 0 0 -1;\ 00206 0 0 -1 0;\ 00207 0 0 1 0;\ 00208 0 0 0 -1;\ 00209 1 0 0 0;\ 00210 0 -1 0 0;\ 00211 0 0 0 1;\ 00212 0 0 1 0;\ 00213 0 1 0 0;\ 00214 1 0 0 0";//B_1; B_2; B_3; B_4 00215 } 00216 else if (code_name=="Golden_2x2")//Golden code as proposed by Belfiore 00217 { 00218 em_antennas = 2;//emission antenna 00219 channel_uses = 2;//channel uses 00220 symb_block = 4;//number of symbols/block 00221 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00222 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00223 std::complex<double> theta((1+std::sqrt(5.0))/2,0); 00224 std::complex<double> theta_b((1-std::sqrt(5.0))/2,0); 00225 std::complex<double> j(0,1); 00226 std::complex<double> one(1,0); 00227 std::complex<double> alpha = one+j*(one-theta); 00228 std::complex<double> alpha_b = one+j*(one-theta_b); 00229 std::complex<double> gamma = j; 00230 A.set_size(8,2); 00231 A(0,0) = alpha/std::sqrt(5.0); 00232 A(0,1) = 0; 00233 A(1,0) = 0; 00234 A(1,1) = alpha_b/std::sqrt(5.0);//A_1 00235 A(2,0) = alpha*theta/std::sqrt(5.0); 00236 A(2,1) = 0; 00237 A(3,0) = 0; 00238 A(3,1) = alpha_b*theta_b/std::sqrt(5.0);//A_2 00239 A(4,0) = 0; 00240 A(4,1) = gamma*alpha_b/std::sqrt(5.0); 00241 A(5,0) = alpha/std::sqrt(5.0); 00242 A(5,1) = 0;//A_3 00243 A(6,0) = 0; 00244 A(6,1) = gamma*alpha_b*theta_b/std::sqrt(5.0); 00245 A(7,0) = alpha*theta/std::sqrt(5.0); 00246 A(7,1) = 0;//A_4 00247 B = A; 00248 } 00249 else if (code_name=="Damen_2x2")//ST code based on number theory as proposed by Damen 00250 { 00251 em_antennas = 2;//emission antenna 00252 channel_uses = 2;//channel uses 00253 symb_block = 4;//number of symbols/block 00254 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00255 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00256 double lambda; 00257 if (const_size==4) 00258 lambda = 0.5; 00259 else if (const_size==16) 00260 lambda = 0.521; 00261 else if (const_size>=256) 00262 lambda = itpp::pi/4; 00263 else 00264 { 00265 lambda = itpp::pi/4; 00266 std::cout << "STC::LDcode: Warning! For " << code_name << " and const. size " << const_size << ", lambda has the value " << lambda << std::endl; 00267 } 00268 std::complex<double> j(0,1); 00269 std::complex<double> phi = std::exp(j*lambda); 00270 std::complex<double> theta = std::exp(j*(lambda/2)); 00271 A.set_size(8, 2); 00272 A(0,0) = 1/std::sqrt(2.0); 00273 A(0,1) = 0; 00274 A(1,0) = 0; 00275 A(1,1) = 1/std::sqrt(2.0);//A_1 00276 A(2,0) = phi/std::sqrt(2.0); 00277 A(2,1) = 0; 00278 A(3,0) = 0; 00279 A(3,1) = -phi/std::sqrt(2.0);//A_2 00280 A(4,0) = 0; 00281 A(4,1) = theta/std::sqrt(2.0); 00282 A(5,0) = theta/std::sqrt(2.0); 00283 A(5,1) = 0;//A_3 00284 A(6,0) = 0; 00285 A(6,1) = -theta*phi/std::sqrt(2.0); 00286 A(7,0) = theta*phi/std::sqrt(2.0); 00287 A(7,1) = 0;//A_4 00288 B = A; 00289 } 00290 else if (code_name=="34ortho_3xN")//rate 3/4 orthogonal code (mutual information 5.13 bits/channel use at rho=20 dB) 00291 { 00292 em_antennas = 3;//emission antenna 00293 channel_uses = 4;//channel uses 00294 symb_block = 3;//number of symbols/block 00295 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00296 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00297 A = "1 0 0;\ 00298 0 1 0;\ 00299 0 0 1;\ 00300 0 0 0;\ 00301 0 1 0;\ 00302 -1 0 0;\ 00303 0 0 0;\ 00304 0 0 1;\ 00305 0 0 1;\ 00306 0 0 0;\ 00307 -1 0 0;\ 00308 0 -1 0";//A_1; A_2; A_3 00309 A /= std::sqrt(double(4)/double(3)); 00310 B = "1 0 0;\ 00311 0 -1 0;\ 00312 0 0 -1;\ 00313 0 0 0;\ 00314 0 1 0;\ 00315 1 0 0;\ 00316 0 0 0;\ 00317 0 0 -1;\ 00318 0 0 1;\ 00319 0 0 0;\ 00320 1 0 0;\ 00321 0 1 0";//B_1; B_2; B_3 00322 B /= std::sqrt(double(4)/double(3)); 00323 } 00324 else if (code_name=="36LD_3xN")//(36) LD code with mutual info. 6.25bits/channel use at rho=20dB 00325 { 00326 em_antennas = 3;//emission antenna 00327 channel_uses = 4;//channel uses 00328 symb_block = 4;//number of symbols/block 00329 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00330 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00331 A.set_size(16, 3); 00332 A(0,0) = 1; 00333 A(0,1) = 0; 00334 A(0,2) = 0; 00335 A(1,0) = 1; 00336 A(1,1) = 1; 00337 A(1,2) = 0; 00338 A(2,0) = 0; 00339 A(2,1) = 0; 00340 A(2,2) = 1; 00341 A(3,0) = 0; 00342 A(3,1) = 0; 00343 A(3,2) = 0;//A_1 00344 A(4,0) = 0; 00345 A(4,1) = 1/std::sqrt(2.0); 00346 A(4,2) = 0; 00347 A(5,0) = -1/std::sqrt(2.0); 00348 A(5,1) = 0; 00349 A(5,2) = -1/std::sqrt(2.0); 00350 A(6,0) = 0; 00351 A(6,1) = 1/std::sqrt(2.0); 00352 A(6,2) = 0; 00353 A(7,0) = 1/std::sqrt(2.0); 00354 A(7,1) = 0; 00355 A(7,2) = -1/std::sqrt(2.0);//A_2 00356 A(8,0) = 1; 00357 A(8,1) = 0; 00358 A(8,2) = 0; 00359 A(9,0) = 0; 00360 A(9,1) = 0; 00361 A(9,2) = 0; 00362 A(10,0) = 0; 00363 A(10,1) = 0; 00364 A(10,2) = -1; 00365 A(11,0) = 0; 00366 A(11,1) = -1; 00367 A(11,2) = 0;//A_3 00368 A(12,0) = 0; 00369 A(12,1) = -1/std::sqrt(2.0); 00370 A(12,2) = 0; 00371 A(13,0) = 1/std::sqrt(2.0); 00372 A(13,1) = 0; 00373 A(13,2) = -1/std::sqrt(2.0); 00374 A(14,0) = 0; 00375 A(14,1) = 1/std::sqrt(2.0); 00376 A(14,2) = 0; 00377 A(15,0) = -1/std::sqrt(2.0); 00378 A(15,1) = 0; 00379 A(15,2) = -1/std::sqrt(2.0);//A_4 00380 B.set_size(16, 3); 00381 B(0,0) = 0; 00382 B(0,1) = -1/std::sqrt(2.0); 00383 B(0,2) = 0; 00384 B(1,0) = -1/std::sqrt(2.0); 00385 B(1,1) = 0; 00386 B(1,2) = 1/std::sqrt(2.0); 00387 B(2,0) = 0; 00388 B(2,1) = 1/std::sqrt(2.0); 00389 B(2,2) = 0; 00390 B(3,0) = 1/std::sqrt(2.0); 00391 B(3,1) = 0; 00392 B(3,2) = 1/std::sqrt(2.0);//B_1 00393 B(4,0) = 1/std::sqrt(2.0); 00394 B(4,1) = double(-1)/double(2); 00395 B(4,2) = 0; 00396 B(5,0) = double(-1)/double(2); 00397 B(5,1) = -1/std::sqrt(2.0); 00398 B(5,2) = double(-1)/double(2); 00399 B(6,0) = 0; 00400 B(6,1) = double(-1)/double(2); 00401 B(6,2) = 1/std::sqrt(2.0); 00402 B(7,0) = double(1)/double(2); 00403 B(7,1) = 0; 00404 B(7,2) = double(-1)/double(2);//B_2 00405 B(8,0) = 1/std::sqrt(2.0); 00406 B(8,1) = double(1)/double(2); 00407 B(8,2) = 0; 00408 B(9,0) = double(1)/double(2); 00409 B(9,1) = -1/std::sqrt(2.0); 00410 B(9,2) = double(1)/double(2); 00411 B(10,0) = 0; 00412 B(10,1) = double(1)/double(2); 00413 B(10,2) = 1/std::sqrt(2.0); 00414 B(11,0) = double(-1)/double(2); 00415 B(11,1) = 0; 00416 B(11,2) = double(1)/double(2);//B_3 00417 B(12,0) = 1; 00418 B(12,1) = 0; 00419 B(12,2) = 0; 00420 B(13,0) = 0; 00421 B(13,1) = 0; 00422 B(13,2) = 0; 00423 B(14,0) = 0; 00424 B(14,1) = 0; 00425 B(14,2) = -1; 00426 B(15,0) = 0; 00427 B(15,1) = 1; 00428 B(15,2) = 0;//B_4 00429 } 00430 else if (code_name=="37LD_3xN")//(37) LD code 3-antenna LD code obtained from the symetrical concatenation of 3 2-antenna orthogonal design 00431 { 00432 em_antennas = 3;//emission antenna 00433 channel_uses = 6;//channel uses 00434 symb_block = 6;//number of symbols/block 00435 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00436 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00437 A = "1 0 0;\ 00438 0 1 0;\ 00439 0 0 0;\ 00440 0 0 0;\ 00441 0 0 0;\ 00442 0 0 0;\ 00443 0 1 0;\ 00444 -1 0 0;\ 00445 0 0 0;\ 00446 0 0 0;\ 00447 0 0 0;\ 00448 0 0 0;\ 00449 0 0 0;\ 00450 0 0 0;\ 00451 0 1 0;\ 00452 0 0 1;\ 00453 0 0 0;\ 00454 0 0 0;\ 00455 0 0 0;\ 00456 0 0 0;\ 00457 0 0 1;\ 00458 0 -1 0;\ 00459 0 0 0;\ 00460 0 0 0;\ 00461 0 0 0;\ 00462 0 0 0;\ 00463 0 0 0;\ 00464 0 0 0;\ 00465 1 0 0;\ 00466 0 0 1;\ 00467 0 0 0;\ 00468 0 0 0;\ 00469 0 0 0;\ 00470 0 0 0;\ 00471 0 0 1;\ 00472 -1 0 0";//A_1; A_2; A_3; A_4; A_5; A_6 00473 A *= std::sqrt(double(3)/double(2)); 00474 B = "1 0 0;\ 00475 0 -1 0;\ 00476 0 0 0;\ 00477 0 0 0;\ 00478 0 0 0;\ 00479 0 0 0;\ 00480 0 1 0;\ 00481 1 0 0;\ 00482 0 0 0;\ 00483 0 0 0;\ 00484 0 0 0;\ 00485 0 0 0;\ 00486 0 0 0;\ 00487 0 0 0;\ 00488 0 1 0;\ 00489 0 0 -1;\ 00490 0 0 0;\ 00491 0 0 0;\ 00492 0 0 0;\ 00493 0 0 0;\ 00494 0 0 1;\ 00495 0 1 0;\ 00496 0 0 0;\ 00497 0 0 0;\ 00498 0 0 0;\ 00499 0 0 0;\ 00500 0 0 0;\ 00501 0 0 0;\ 00502 1 0 0;\ 00503 0 0 -1;\ 00504 0 0 0;\ 00505 0 0 0;\ 00506 0 0 0;\ 00507 0 0 0;\ 00508 0 0 1;\ 00509 1 0 0";//B_1; B_2; B_3; B_4; B_5; B_6 00510 B *= std::sqrt(double(3)/double(2)); 00511 } 00512 else if (code_name=="39LD_3xN") 00513 { 00514 em_antennas = 3;//emission antenna 00515 channel_uses = 6;//channel uses 00516 symb_block = 6;//number of symbols/block 00517 std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl; 00518 std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl; 00519 A.set_size(36, 3); 00520 A(0,0) = 1/std::sqrt(2.0); 00521 A(0,1) = 0; 00522 A(0,2) = 0; 00523 A(1,0) = 0; 00524 A(1,1) = 1/std::sqrt(2.0); 00525 A(1,2) = 0; 00526 A(2,0) = 0; 00527 A(2,1) = 1/std::sqrt(2.0); 00528 A(2,2) = 0; 00529 A(3,0) = 0; 00530 A(3,1) = 0; 00531 A(3,2) = 1/std::sqrt(2.0); 00532 A(4,0) = 1/std::sqrt(2.0); 00533 A(4,1) = 0; 00534 A(4,2) = 0; 00535 A(5,0) = 0; 00536 A(5,1) = 0; 00537 A(5,2) = 1/std::sqrt(2.0);//A_1 00538 A(6,0) = 0; 00539 A(6,1) = 1/std::sqrt(2.0); 00540 A(6,2) = 0; 00541 A(7,0) = -1/std::sqrt(2.0); 00542 A(7,1) = 0; 00543 A(7,2) = 0; 00544 A(8,0) = 0; 00545 A(8,1) = 0; 00546 A(8,2) = 1/std::sqrt(2.0); 00547 A(9,0) = 0; 00548 A(9,1) = -1/std::sqrt(2.0); 00549 A(9,2) = 0; 00550 A(10,0) = 0; 00551 A(10,1) = 0; 00552 A(10,2) = 1/std::sqrt(2.0); 00553 A(11,0) = -1/std::sqrt(2.0); 00554 A(11,1) = 0; 00555 A(11,2) = 0;//A_2 00556 A(12,0) = 1/std::sqrt(2.0); 00557 A(12,1) = 0; 00558 A(12,2) = 0; 00559 A(13,0) = 0; 00560 A(13,1) = 1/std::sqrt(2.0); 00561 A(13,2) = 0; 00562 A(14,0) = 0; 00563 A(14,1) = -1/(2*std::sqrt(2.0)); 00564 A(14,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00565 A(15,0) = 0; 00566 A(15,1) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00567 A(15,2) = -1/(2*std::sqrt(2.0)); 00568 A(16,0) = -1/(2*std::sqrt(2.0)); 00569 A(16,1) = 0; 00570 A(16,2) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00571 A(17,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00572 A(17,1) = 0; 00573 A(17,2) = -1/(2*std::sqrt(2.0));//A_3 00574 A(18,0) = 0; 00575 A(18,1) = 1/std::sqrt(2.0); 00576 A(18,2) = 0; 00577 A(19,0) = -1/std::sqrt(2.0); 00578 A(19,1) = 0; 00579 A(19,2) = 0; 00580 A(20,0) = 0; 00581 A(20,1) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00582 A(20,2) = -1/(2*std::sqrt(2.0)); 00583 A(21,0) = 0; 00584 A(21,1) = 1/(2*std::sqrt(2.0)); 00585 A(21,2) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00586 A(22,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00587 A(22,1) = 0; 00588 A(22,2) = -1/(2*std::sqrt(2.0)); 00589 A(23,0) = 1/(2*std::sqrt(2.0)); 00590 A(23,1) = 0; 00591 A(23,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));//A_4 00592 A(24,0) = 1/std::sqrt(2.0); 00593 A(24,1) = 0; 00594 A(24,2) = 0; 00595 A(25,0) = 0; 00596 A(25,1) = 1/std::sqrt(2.0); 00597 A(25,2) = 0; 00598 A(26,0) = 0; 00599 A(26,1) = -1/(2*std::sqrt(2.0)); 00600 A(26,2) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00601 A(27,0) = 0; 00602 A(27,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00603 A(27,2) = -1/(2*std::sqrt(2.0)); 00604 A(28,0) = -1/(2*std::sqrt(2.0)); 00605 A(28,1) = 0; 00606 A(28,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00607 A(29,0) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00608 A(29,1) = 0; 00609 A(29,2) = -1/(2*std::sqrt(2.0));//A_5 00610 A(30,0) = 0; 00611 A(30,1) = 1/std::sqrt(2.0); 00612 A(30,2) = 0; 00613 A(31,0) = -1/std::sqrt(2.0); 00614 A(31,1) = 0; 00615 A(31,2) = 0; 00616 A(32,0) = 0; 00617 A(32,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00618 A(32,2) = -1/(2*std::sqrt(2.0)); 00619 A(33,0) = 0; 00620 A(33,1) = 1/(2*std::sqrt(2.0)); 00621 A(33,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00622 A(34,0) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00623 A(34,1) = 0; 00624 A(34,2) = -1/(2*std::sqrt(2.0)); 00625 A(35,0) = 1/(2*std::sqrt(2.0)); 00626 A(35,1) = 0; 00627 A(35,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));//A_6 00628 B.set_size(36, 3); 00629 B(0,0) = 1/std::sqrt(2.0); 00630 B(0,1) = 0; 00631 B(0,2) = 0; 00632 B(1,0) = 0; 00633 B(1,1) = -1/std::sqrt(2.0); 00634 B(1,2) = 0; 00635 B(2,0) = 0; 00636 B(2,1) = 1/std::sqrt(2.0); 00637 B(2,2) = 0; 00638 B(3,0) = 0; 00639 B(3,1) = 0; 00640 B(3,2) = -1/std::sqrt(2.0); 00641 B(4,0) = 1/std::sqrt(2.0); 00642 B(4,1) = 0; 00643 B(4,2) = 0; 00644 B(5,0) = 0; 00645 B(5,1) = 0; 00646 B(5,2) = -1/std::sqrt(2.0);//B_1 00647 B(6,0) = 0; 00648 B(6,1) = 1/std::sqrt(2.0); 00649 B(6,2) = 0; 00650 B(7,0) = 1/std::sqrt(2.0); 00651 B(7,1) = 0; 00652 B(7,2) = 0; 00653 B(8,0) = 0; 00654 B(8,1) = 0; 00655 B(8,2) = 1/std::sqrt(2.0); 00656 B(9,0) = 0; 00657 B(9,1) = 1/std::sqrt(2.0); 00658 B(9,2) = 0; 00659 B(10,0) = 0; 00660 B(10,1) = 0; 00661 B(10,2) = 1/std::sqrt(2.0); 00662 B(11,0) = 1/std::sqrt(2.0); 00663 B(11,1) = 0; 00664 B(11,2) = 0;//B_2 00665 B(12,0) = 1/std::sqrt(2.0); 00666 B(12,1) = 0; 00667 B(12,2) = 0; 00668 B(13,0) = 0; 00669 B(13,1) = -1/std::sqrt(2.0); 00670 B(13,2) = 0; 00671 B(14,0) = 0; 00672 B(14,1) = -1/(2*std::sqrt(2.0)); 00673 B(14,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00674 B(15,0) = 0; 00675 B(15,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00676 B(15,2) = 1/(2*std::sqrt(2.0)); 00677 B(16,0) = -1/(2*std::sqrt(2.0)); 00678 B(16,1) = 0; 00679 B(16,2) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00680 B(17,0) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00681 B(17,1) = 0; 00682 B(17,2) = 1/(2*std::sqrt(2.0));//B_3 00683 B(18,0) = 0; 00684 B(18,1) = 1/std::sqrt(2.0); 00685 B(18,2) = 0; 00686 B(19,0) = 1/std::sqrt(2.0); 00687 B(19,1) = 0; 00688 B(19,2) = 0; 00689 B(20,0) = 0; 00690 B(20,1) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00691 B(20,2) = -1/(2*std::sqrt(2.0)); 00692 B(21,0) = 0; 00693 B(21,1) = -1/(2*std::sqrt(2.0)); 00694 B(21,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00695 B(22,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00696 B(22,1) = 0; 00697 B(22,2) = -1/(2*std::sqrt(2.0)); 00698 B(23,0) = -1/(2*std::sqrt(2.0)); 00699 B(23,1) = 0; 00700 B(23,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));//B_4 00701 B(24,0) = 1/std::sqrt(2.0); 00702 B(24,1) = 0; 00703 B(24,2) = 0; 00704 B(25,0) = 0; 00705 B(25,1) = -1/std::sqrt(2.0); 00706 B(25,2) = 0; 00707 B(26,0) = 0; 00708 B(26,1) = -1/(2*std::sqrt(2.0)); 00709 B(26,2) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00710 B(27,0) = 0; 00711 B(27,1) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00712 B(27,2) = 1/(2*std::sqrt(2.0)); 00713 B(28,0) = -1/(2*std::sqrt(2.0)); 00714 B(28,1) = 0; 00715 B(28,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00716 B(29,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00717 B(29,1) = 0; 00718 B(29,2) = 1/(2*std::sqrt(2.0));//B_5 00719 B(30,0) = 0; 00720 B(30,1) = 1/std::sqrt(2.0); 00721 B(30,2) = 0; 00722 B(31,0) = 1/std::sqrt(2.0); 00723 B(31,1) = 0; 00724 B(31,2) = 0; 00725 B(32,0) = 0; 00726 B(32,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0)); 00727 B(32,2) = -1/(2*std::sqrt(2.0)); 00728 B(33,0) = 0; 00729 B(33,1) = -1/(2*std::sqrt(2.0)); 00730 B(33,2) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00731 B(34,0) = std::sqrt(3.0)/(2*std::sqrt(2.0)); 00732 B(34,1) = 0; 00733 B(34,2) = -1/(2*std::sqrt(2.0)); 00734 B(35,0) = -1/(2*std::sqrt(2.0)); 00735 B(35,1) = 0; 00736 B(35,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));//B_6 00737 } 00738 else 00739 std::cout << "STC::LDcode: unknown code name. Available codes are: V-BLAST_MxN, imp_V-BLAST_MxN, Alamouti_2xN, \ 00740 Switched_Alamouti_4xN, Double_Alamouti_4xN, Jafarkhani_4xN, Golden_2x2, Damen_2x2, 34ortho_3xN, 36LD_3xN, 37LD_3xN, 39LD_3xN" << std::endl; 00741 } 00742 00743 itpp::cmat STC::Hassibi_encode(const itpp::cvec &symb) 00744 //LD code generation (symb_block symbols go to an channel_uses x em_antennas matrix) following Hassibi's approach 00745 { 00746 int nb_subblocks = symb.length()/symb_block; 00747 int tx_duration = channel_uses*nb_subblocks; 00748 itpp::cmat S(tx_duration,em_antennas); 00749 itpp::cmat temp(channel_uses,em_antennas); 00750 std::complex<double> j(0,1); 00751 register int ns,k; 00752 for (ns=0; ns<nb_subblocks; ns++)//encode block by block (symb_block symbols) 00753 { 00754 temp.zeros(); 00755 for (k=0; k<symb_block; k++)//sum over all symb_block matrices 00756 temp += (A(k*channel_uses,(k+1)*channel_uses-1,0,em_antennas-1)*static_cast< std::complex<double> >(symb(k+ns*symb_block).real())\ 00757 +j*B(k*channel_uses,(k+1)*channel_uses-1,0,em_antennas-1)*static_cast< std::complex<double> >(symb(k+ns*symb_block).imag())); 00758 S.set_submatrix(ns*channel_uses, 0, temp); 00759 } 00760 return S; 00761 } 00762 00763 inline itpp::cmat STC::diag_pow(const itpp::cmat &in_mat, const double &in_exp) 00764 //first input should be a diagonal square matrix with complex elements 00765 { 00766 register int n; 00767 int dim = in_mat.rows(); 00768 itpp::cmat out_mat(dim,dim); 00769 for (n=0; n<dim; n++) 00770 out_mat(n,n) = std::pow(in_mat(n,n), in_exp); 00771 return out_mat; 00772 } 00773 00774 inline itpp::mat STC::mat_pow(const itpp::mat &in_mat, const int &in_exp) 00775 //square matrix power of integer exponent 00776 { 00777 if (in_exp==0) 00778 return itpp::eye(in_mat.rows()); 00779 itpp::mat out = in_mat; 00780 int abs_in_exp = std::abs(in_exp); 00781 register int n; 00782 for (n=1; n<abs_in_exp; n++) 00783 out *= in_mat; 00784 return (in_exp>0)?out:itpp::inv(out); 00785 } 00786 00787 }
Generated on Sat Jul 9 2011 15:21:32 for IT++ by Doxygen 1.7.4