IT++ Logo
stc.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Sat Jul 9 2011 15:21:32 for IT++ by Doxygen 1.7.4