IT++ Logo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
stc.cpp
Go to the documentation of this file.
1 
29 #include <itpp/comm/stc.h>
30 
31 namespace itpp
32 {
33 
34 void STC::Hassibi_block_code(void)
35 /* this function implements the A and B matrices needed for Space-Time block codes generation following the Hassibi's approach:
36  * S = sum_{q=1}^symb_block (A_q alpha_q + jB_q beta_q),
37  * where s_q = alpha_q+jbeta_q is the symbol after modulation
38  * each A_q and B_q matrix has dimension TxM
39  * different A_q and B_q matrices are stacked one below the other, e.g. [A_1;A_2;...;A_Q]
40 
41  * input: code_name - code name whose generator matrices are to be generated
42  * const_size - constellation size (used in Damen code)
43  * ouputs: symb_block - number of symbols per block
44  * A, B - generator matrices
45  * inputs/ouputs: for some codes these are inputs for others they are
46  * predefined, so they are outputs only
47  * em_antennas - number of emission antenna
48  * channel_uses - channel uses
49  */
50 {
51  if (code_name=="V-BLAST_MxN")//classical V-BLAST
52  {
53  symb_block = channel_uses*em_antennas;//number of symbols/block
54  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameter is predefined:" << std::endl;
55  std::cout << "symb_block = channel_uses*em_antennas = " << symb_block << std::endl;
56  A.set_size(symb_block*channel_uses, em_antennas);
57  A.zeros();
58  itpp::mat temp(channel_uses, em_antennas);
59  temp.zeros();
60  register int tau,m;
61  for (tau=0; tau<channel_uses; tau++)
62  {
63  for (m=0; m<em_antennas; m++)
64  {
65  temp(tau,m) = 1;
66  A.set_submatrix((em_antennas*(tau-1)+m-1), 0, to_cmat(temp));
67  temp(tau,m) = 0;
68  }
69  }
70  B = A;
71  }
72  else if (code_name=="imp_V-BLAST_MxN")//improved V-BLAST (code (31) in Hassibi's paper)
73  {
74  if (channel_uses!=em_antennas)
75  {
76  std::cout << "STC::LDcode: Warning! For " << code_name << " channel_uses and em_antennas must be equal. Choosing channel_uses=em_antennas" << std::endl;
77  channel_uses = em_antennas;
78  }
79  symb_block = channel_uses*em_antennas;//number of symbols/block
80  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameter is predefined:" << std::endl;
81  std::cout << "symb_block = " << symb_block << std::endl;
82  std::complex<double> j(0,1);
83  itpp::cmat D = itpp::diag(exp(j*(2*itpp::pi/em_antennas)*itpp::linspace(0, em_antennas-1, em_antennas)));
84  itpp::mat P = itpp::diag(itpp::ones(em_antennas-1), -1);
85  P(0,em_antennas-1) = 1;
86  A.set_size(symb_block*channel_uses, em_antennas);
87  A.zeros();
88  register int k,l;
89  for (k=0; k<channel_uses; k++)
90  for (l=0; l<em_antennas; l++)
91  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)));
92  B = A;
93  }
94  else if (code_name=="Alamouti_2xN")//Alamouti's orthogonal code
95  {
96  em_antennas = 2;//emission antenna
97  channel_uses = 2;//channel uses
98  symb_block = 2;//number of symbols/block
99  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
100  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
101  A = "1 0;\
102  0 1;\
103  0 1;\
104  -1 0";//A_1; A_2
105  B = "1 0;\
106  0 -1;\
107  0 1;\
108  1 0";//B_1; B_2
109  }
110  else if (code_name=="Switched_Alamouti_4xN")
111  {
112  em_antennas = 4;//emission antenna
113  channel_uses = 4;//channel uses
114  symb_block = 4;//number of symbols/block
115  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
116  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
117  A = "1 0 0 0;\
118  0 1 0 0;\
119  0 0 0 0;\
120  0 0 0 0;\
121  0 1 0 0;\
122  -1 0 0 0;\
123  0 0 0 0;\
124  0 0 0 0;\
125  0 0 0 0;\
126  0 0 0 0;\
127  0 0 1 0;\
128  0 0 0 1;\
129  0 0 0 0;\
130  0 0 0 0;\
131  0 0 0 1;\
132  0 0 -1 0";//A_1; A_2; A_3; A_4
133  A *= std::sqrt(2.0);//normalization
134  B = "1 0 0 0;\
135  0 -1 0 0;\
136  0 0 0 0;\
137  0 0 0 0;\
138  0 1 0 0;\
139  1 0 0 0;\
140  0 0 0 0;\
141  0 0 0 0;\
142  0 0 0 0;\
143  0 0 0 0;\
144  0 0 1 0;\
145  0 0 0 -1;\
146  0 0 0 0;\
147  0 0 0 0;\
148  0 0 0 1;\
149  0 0 1 0";//B_1; B_2; B_3; B_4
150  B *= std::sqrt(2.0);
151  }
152  else if (code_name=="Double_Alamouti_4xN")
153  {
154  em_antennas = 4;//emission antenna
155  channel_uses = 2;//channel uses
156  symb_block = 4;//number of symbols/block
157  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
158  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
159  A = "1 0 0 0;\
160  0 1 0 0;\
161  0 0 1 0;\
162  0 0 0 1;\
163  0 1 0 0;\
164  -1 0 0 0;\
165  0 0 0 1;\
166  0 0 -1 0";//A_1; A_2; A_3; A_4
167  B = "1 0 0 0;\
168  0 -1 0 0;\
169  0 0 1 0;\
170  0 0 0 -1;\
171  0 1 0 0;\
172  1 0 0 0;\
173  0 0 0 1;\
174  0 0 1 0";//B_1; B_2; B_3; B_4
175  }
176  else if (code_name=="Jafarkhani_4xN")//Jafarkhani's quasi-orthogonal code
177  {
178  em_antennas = 4;//emission antenna
179  channel_uses = 4;//channel uses
180  symb_block = 4;//number of symbols/block
181  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
182  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
183  A = "1 0 0 0;\
184  0 1 0 0;\
185  0 0 1 0;\
186  0 0 0 1;\
187  0 1 0 0;\
188  -1 0 0 0;\
189  0 0 0 1;\
190  0 0 -1 0;\
191  0 0 1 0;\
192  0 0 0 1;\
193  -1 0 0 0;\
194  0 -1 0 0;\
195  0 0 0 1;\
196  0 0 -1 0;\
197  0 -1 0 0;\
198  1 0 0 0";//A_1; A_2; A_3; A_4
199  B = "1 0 0 0;\
200  0 -1 0 0;\
201  0 0 -1 0;\
202  0 0 0 1;\
203  0 1 0 0;\
204  1 0 0 0;\
205  0 0 0 -1;\
206  0 0 -1 0;\
207  0 0 1 0;\
208  0 0 0 -1;\
209  1 0 0 0;\
210  0 -1 0 0;\
211  0 0 0 1;\
212  0 0 1 0;\
213  0 1 0 0;\
214  1 0 0 0";//B_1; B_2; B_3; B_4
215  }
216  else if (code_name=="Golden_2x2")//Golden code as proposed by Belfiore
217  {
218  em_antennas = 2;//emission antenna
219  channel_uses = 2;//channel uses
220  symb_block = 4;//number of symbols/block
221  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
222  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
223  std::complex<double> theta((1+std::sqrt(5.0))/2,0);
224  std::complex<double> theta_b((1-std::sqrt(5.0))/2,0);
225  std::complex<double> j(0,1);
226  std::complex<double> one(1,0);
227  std::complex<double> alpha = one+j*(one-theta);
228  std::complex<double> alpha_b = one+j*(one-theta_b);
229  std::complex<double> gamma = j;
230  A.set_size(8,2);
231  A(0,0) = alpha/std::sqrt(5.0);
232  A(0,1) = 0;
233  A(1,0) = 0;
234  A(1,1) = alpha_b/std::sqrt(5.0);//A_1
235  A(2,0) = alpha*theta/std::sqrt(5.0);
236  A(2,1) = 0;
237  A(3,0) = 0;
238  A(3,1) = alpha_b*theta_b/std::sqrt(5.0);//A_2
239  A(4,0) = 0;
240  A(4,1) = gamma*alpha_b/std::sqrt(5.0);
241  A(5,0) = alpha/std::sqrt(5.0);
242  A(5,1) = 0;//A_3
243  A(6,0) = 0;
244  A(6,1) = gamma*alpha_b*theta_b/std::sqrt(5.0);
245  A(7,0) = alpha*theta/std::sqrt(5.0);
246  A(7,1) = 0;//A_4
247  B = A;
248  }
249  else if (code_name=="Damen_2x2")//ST code based on number theory as proposed by Damen
250  {
251  em_antennas = 2;//emission antenna
252  channel_uses = 2;//channel uses
253  symb_block = 4;//number of symbols/block
254  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
255  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
256  double lambda;
257  if (const_size==4)
258  lambda = 0.5;
259  else if (const_size==16)
260  lambda = 0.521;
261  else if (const_size>=256)
262  lambda = itpp::pi/4;
263  else
264  {
265  lambda = itpp::pi/4;
266  std::cout << "STC::LDcode: Warning! For " << code_name << " and const. size " << const_size << ", lambda has the value " << lambda << std::endl;
267  }
268  std::complex<double> j(0,1);
269  std::complex<double> phi = std::exp(j*lambda);
270  std::complex<double> theta = std::exp(j*(lambda/2));
271  A.set_size(8, 2);
272  A(0,0) = 1/std::sqrt(2.0);
273  A(0,1) = 0;
274  A(1,0) = 0;
275  A(1,1) = 1/std::sqrt(2.0);//A_1
276  A(2,0) = phi/std::sqrt(2.0);
277  A(2,1) = 0;
278  A(3,0) = 0;
279  A(3,1) = -phi/std::sqrt(2.0);//A_2
280  A(4,0) = 0;
281  A(4,1) = theta/std::sqrt(2.0);
282  A(5,0) = theta/std::sqrt(2.0);
283  A(5,1) = 0;//A_3
284  A(6,0) = 0;
285  A(6,1) = -theta*phi/std::sqrt(2.0);
286  A(7,0) = theta*phi/std::sqrt(2.0);
287  A(7,1) = 0;//A_4
288  B = A;
289  }
290  else if (code_name=="34ortho_3xN")//rate 3/4 orthogonal code (mutual information 5.13 bits/channel use at rho=20 dB)
291  {
292  em_antennas = 3;//emission antenna
293  channel_uses = 4;//channel uses
294  symb_block = 3;//number of symbols/block
295  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
296  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
297  A = "1 0 0;\
298  0 1 0;\
299  0 0 1;\
300  0 0 0;\
301  0 1 0;\
302  -1 0 0;\
303  0 0 0;\
304  0 0 1;\
305  0 0 1;\
306  0 0 0;\
307  -1 0 0;\
308  0 -1 0";//A_1; A_2; A_3
309  A /= std::sqrt(double(4)/double(3));
310  B = "1 0 0;\
311  0 -1 0;\
312  0 0 -1;\
313  0 0 0;\
314  0 1 0;\
315  1 0 0;\
316  0 0 0;\
317  0 0 -1;\
318  0 0 1;\
319  0 0 0;\
320  1 0 0;\
321  0 1 0";//B_1; B_2; B_3
322  B /= std::sqrt(double(4)/double(3));
323  }
324  else if (code_name=="36LD_3xN")//(36) LD code with mutual info. 6.25bits/channel use at rho=20dB
325  {
326  em_antennas = 3;//emission antenna
327  channel_uses = 4;//channel uses
328  symb_block = 4;//number of symbols/block
329  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
330  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
331  A.set_size(16, 3);
332  A(0,0) = 1;
333  A(0,1) = 0;
334  A(0,2) = 0;
335  A(1,0) = 1;
336  A(1,1) = 1;
337  A(1,2) = 0;
338  A(2,0) = 0;
339  A(2,1) = 0;
340  A(2,2) = 1;
341  A(3,0) = 0;
342  A(3,1) = 0;
343  A(3,2) = 0;//A_1
344  A(4,0) = 0;
345  A(4,1) = 1/std::sqrt(2.0);
346  A(4,2) = 0;
347  A(5,0) = -1/std::sqrt(2.0);
348  A(5,1) = 0;
349  A(5,2) = -1/std::sqrt(2.0);
350  A(6,0) = 0;
351  A(6,1) = 1/std::sqrt(2.0);
352  A(6,2) = 0;
353  A(7,0) = 1/std::sqrt(2.0);
354  A(7,1) = 0;
355  A(7,2) = -1/std::sqrt(2.0);//A_2
356  A(8,0) = 1;
357  A(8,1) = 0;
358  A(8,2) = 0;
359  A(9,0) = 0;
360  A(9,1) = 0;
361  A(9,2) = 0;
362  A(10,0) = 0;
363  A(10,1) = 0;
364  A(10,2) = -1;
365  A(11,0) = 0;
366  A(11,1) = -1;
367  A(11,2) = 0;//A_3
368  A(12,0) = 0;
369  A(12,1) = -1/std::sqrt(2.0);
370  A(12,2) = 0;
371  A(13,0) = 1/std::sqrt(2.0);
372  A(13,1) = 0;
373  A(13,2) = -1/std::sqrt(2.0);
374  A(14,0) = 0;
375  A(14,1) = 1/std::sqrt(2.0);
376  A(14,2) = 0;
377  A(15,0) = -1/std::sqrt(2.0);
378  A(15,1) = 0;
379  A(15,2) = -1/std::sqrt(2.0);//A_4
380  B.set_size(16, 3);
381  B(0,0) = 0;
382  B(0,1) = -1/std::sqrt(2.0);
383  B(0,2) = 0;
384  B(1,0) = -1/std::sqrt(2.0);
385  B(1,1) = 0;
386  B(1,2) = 1/std::sqrt(2.0);
387  B(2,0) = 0;
388  B(2,1) = 1/std::sqrt(2.0);
389  B(2,2) = 0;
390  B(3,0) = 1/std::sqrt(2.0);
391  B(3,1) = 0;
392  B(3,2) = 1/std::sqrt(2.0);//B_1
393  B(4,0) = 1/std::sqrt(2.0);
394  B(4,1) = double(-1)/double(2);
395  B(4,2) = 0;
396  B(5,0) = double(-1)/double(2);
397  B(5,1) = -1/std::sqrt(2.0);
398  B(5,2) = double(-1)/double(2);
399  B(6,0) = 0;
400  B(6,1) = double(-1)/double(2);
401  B(6,2) = 1/std::sqrt(2.0);
402  B(7,0) = double(1)/double(2);
403  B(7,1) = 0;
404  B(7,2) = double(-1)/double(2);//B_2
405  B(8,0) = 1/std::sqrt(2.0);
406  B(8,1) = double(1)/double(2);
407  B(8,2) = 0;
408  B(9,0) = double(1)/double(2);
409  B(9,1) = -1/std::sqrt(2.0);
410  B(9,2) = double(1)/double(2);
411  B(10,0) = 0;
412  B(10,1) = double(1)/double(2);
413  B(10,2) = 1/std::sqrt(2.0);
414  B(11,0) = double(-1)/double(2);
415  B(11,1) = 0;
416  B(11,2) = double(1)/double(2);//B_3
417  B(12,0) = 1;
418  B(12,1) = 0;
419  B(12,2) = 0;
420  B(13,0) = 0;
421  B(13,1) = 0;
422  B(13,2) = 0;
423  B(14,0) = 0;
424  B(14,1) = 0;
425  B(14,2) = -1;
426  B(15,0) = 0;
427  B(15,1) = 1;
428  B(15,2) = 0;//B_4
429  }
430  else if (code_name=="37LD_3xN")//(37) LD code 3-antenna LD code obtained from the symetrical concatenation of 3 2-antenna orthogonal design
431  {
432  em_antennas = 3;//emission antenna
433  channel_uses = 6;//channel uses
434  symb_block = 6;//number of symbols/block
435  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
436  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
437  A = "1 0 0;\
438  0 1 0;\
439  0 0 0;\
440  0 0 0;\
441  0 0 0;\
442  0 0 0;\
443  0 1 0;\
444  -1 0 0;\
445  0 0 0;\
446  0 0 0;\
447  0 0 0;\
448  0 0 0;\
449  0 0 0;\
450  0 0 0;\
451  0 1 0;\
452  0 0 1;\
453  0 0 0;\
454  0 0 0;\
455  0 0 0;\
456  0 0 0;\
457  0 0 1;\
458  0 -1 0;\
459  0 0 0;\
460  0 0 0;\
461  0 0 0;\
462  0 0 0;\
463  0 0 0;\
464  0 0 0;\
465  1 0 0;\
466  0 0 1;\
467  0 0 0;\
468  0 0 0;\
469  0 0 0;\
470  0 0 0;\
471  0 0 1;\
472  -1 0 0";//A_1; A_2; A_3; A_4; A_5; A_6
473  A *= std::sqrt(double(3)/double(2));
474  B = "1 0 0;\
475  0 -1 0;\
476  0 0 0;\
477  0 0 0;\
478  0 0 0;\
479  0 0 0;\
480  0 1 0;\
481  1 0 0;\
482  0 0 0;\
483  0 0 0;\
484  0 0 0;\
485  0 0 0;\
486  0 0 0;\
487  0 0 0;\
488  0 1 0;\
489  0 0 -1;\
490  0 0 0;\
491  0 0 0;\
492  0 0 0;\
493  0 0 0;\
494  0 0 1;\
495  0 1 0;\
496  0 0 0;\
497  0 0 0;\
498  0 0 0;\
499  0 0 0;\
500  0 0 0;\
501  0 0 0;\
502  1 0 0;\
503  0 0 -1;\
504  0 0 0;\
505  0 0 0;\
506  0 0 0;\
507  0 0 0;\
508  0 0 1;\
509  1 0 0";//B_1; B_2; B_3; B_4; B_5; B_6
510  B *= std::sqrt(double(3)/double(2));
511  }
512  else if (code_name=="39LD_3xN")
513  {
514  em_antennas = 3;//emission antenna
515  channel_uses = 6;//channel uses
516  symb_block = 6;//number of symbols/block
517  std::cout << "STC::LDcode: Warning! For " << code_name << " the following parameters are predefined:" << std::endl;
518  std::cout << "em_antennas = " << em_antennas << ", channel_uses = " << channel_uses << ", symb_block = " << symb_block << std::endl;
519  A.set_size(36, 3);
520  A(0,0) = 1/std::sqrt(2.0);
521  A(0,1) = 0;
522  A(0,2) = 0;
523  A(1,0) = 0;
524  A(1,1) = 1/std::sqrt(2.0);
525  A(1,2) = 0;
526  A(2,0) = 0;
527  A(2,1) = 1/std::sqrt(2.0);
528  A(2,2) = 0;
529  A(3,0) = 0;
530  A(3,1) = 0;
531  A(3,2) = 1/std::sqrt(2.0);
532  A(4,0) = 1/std::sqrt(2.0);
533  A(4,1) = 0;
534  A(4,2) = 0;
535  A(5,0) = 0;
536  A(5,1) = 0;
537  A(5,2) = 1/std::sqrt(2.0);//A_1
538  A(6,0) = 0;
539  A(6,1) = 1/std::sqrt(2.0);
540  A(6,2) = 0;
541  A(7,0) = -1/std::sqrt(2.0);
542  A(7,1) = 0;
543  A(7,2) = 0;
544  A(8,0) = 0;
545  A(8,1) = 0;
546  A(8,2) = 1/std::sqrt(2.0);
547  A(9,0) = 0;
548  A(9,1) = -1/std::sqrt(2.0);
549  A(9,2) = 0;
550  A(10,0) = 0;
551  A(10,1) = 0;
552  A(10,2) = 1/std::sqrt(2.0);
553  A(11,0) = -1/std::sqrt(2.0);
554  A(11,1) = 0;
555  A(11,2) = 0;//A_2
556  A(12,0) = 1/std::sqrt(2.0);
557  A(12,1) = 0;
558  A(12,2) = 0;
559  A(13,0) = 0;
560  A(13,1) = 1/std::sqrt(2.0);
561  A(13,2) = 0;
562  A(14,0) = 0;
563  A(14,1) = -1/(2*std::sqrt(2.0));
564  A(14,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
565  A(15,0) = 0;
566  A(15,1) = std::sqrt(3.0)/(2*std::sqrt(2.0));
567  A(15,2) = -1/(2*std::sqrt(2.0));
568  A(16,0) = -1/(2*std::sqrt(2.0));
569  A(16,1) = 0;
570  A(16,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
571  A(17,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
572  A(17,1) = 0;
573  A(17,2) = -1/(2*std::sqrt(2.0));//A_3
574  A(18,0) = 0;
575  A(18,1) = 1/std::sqrt(2.0);
576  A(18,2) = 0;
577  A(19,0) = -1/std::sqrt(2.0);
578  A(19,1) = 0;
579  A(19,2) = 0;
580  A(20,0) = 0;
581  A(20,1) = std::sqrt(3.0)/(2*std::sqrt(2.0));
582  A(20,2) = -1/(2*std::sqrt(2.0));
583  A(21,0) = 0;
584  A(21,1) = 1/(2*std::sqrt(2.0));
585  A(21,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
586  A(22,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
587  A(22,1) = 0;
588  A(22,2) = -1/(2*std::sqrt(2.0));
589  A(23,0) = 1/(2*std::sqrt(2.0));
590  A(23,1) = 0;
591  A(23,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));//A_4
592  A(24,0) = 1/std::sqrt(2.0);
593  A(24,1) = 0;
594  A(24,2) = 0;
595  A(25,0) = 0;
596  A(25,1) = 1/std::sqrt(2.0);
597  A(25,2) = 0;
598  A(26,0) = 0;
599  A(26,1) = -1/(2*std::sqrt(2.0));
600  A(26,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
601  A(27,0) = 0;
602  A(27,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
603  A(27,2) = -1/(2*std::sqrt(2.0));
604  A(28,0) = -1/(2*std::sqrt(2.0));
605  A(28,1) = 0;
606  A(28,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
607  A(29,0) = std::sqrt(3.0)/(2*std::sqrt(2.0));
608  A(29,1) = 0;
609  A(29,2) = -1/(2*std::sqrt(2.0));//A_5
610  A(30,0) = 0;
611  A(30,1) = 1/std::sqrt(2.0);
612  A(30,2) = 0;
613  A(31,0) = -1/std::sqrt(2.0);
614  A(31,1) = 0;
615  A(31,2) = 0;
616  A(32,0) = 0;
617  A(32,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
618  A(32,2) = -1/(2*std::sqrt(2.0));
619  A(33,0) = 0;
620  A(33,1) = 1/(2*std::sqrt(2.0));
621  A(33,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
622  A(34,0) = std::sqrt(3.0)/(2*std::sqrt(2.0));
623  A(34,1) = 0;
624  A(34,2) = -1/(2*std::sqrt(2.0));
625  A(35,0) = 1/(2*std::sqrt(2.0));
626  A(35,1) = 0;
627  A(35,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));//A_6
628  B.set_size(36, 3);
629  B(0,0) = 1/std::sqrt(2.0);
630  B(0,1) = 0;
631  B(0,2) = 0;
632  B(1,0) = 0;
633  B(1,1) = -1/std::sqrt(2.0);
634  B(1,2) = 0;
635  B(2,0) = 0;
636  B(2,1) = 1/std::sqrt(2.0);
637  B(2,2) = 0;
638  B(3,0) = 0;
639  B(3,1) = 0;
640  B(3,2) = -1/std::sqrt(2.0);
641  B(4,0) = 1/std::sqrt(2.0);
642  B(4,1) = 0;
643  B(4,2) = 0;
644  B(5,0) = 0;
645  B(5,1) = 0;
646  B(5,2) = -1/std::sqrt(2.0);//B_1
647  B(6,0) = 0;
648  B(6,1) = 1/std::sqrt(2.0);
649  B(6,2) = 0;
650  B(7,0) = 1/std::sqrt(2.0);
651  B(7,1) = 0;
652  B(7,2) = 0;
653  B(8,0) = 0;
654  B(8,1) = 0;
655  B(8,2) = 1/std::sqrt(2.0);
656  B(9,0) = 0;
657  B(9,1) = 1/std::sqrt(2.0);
658  B(9,2) = 0;
659  B(10,0) = 0;
660  B(10,1) = 0;
661  B(10,2) = 1/std::sqrt(2.0);
662  B(11,0) = 1/std::sqrt(2.0);
663  B(11,1) = 0;
664  B(11,2) = 0;//B_2
665  B(12,0) = 1/std::sqrt(2.0);
666  B(12,1) = 0;
667  B(12,2) = 0;
668  B(13,0) = 0;
669  B(13,1) = -1/std::sqrt(2.0);
670  B(13,2) = 0;
671  B(14,0) = 0;
672  B(14,1) = -1/(2*std::sqrt(2.0));
673  B(14,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
674  B(15,0) = 0;
675  B(15,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
676  B(15,2) = 1/(2*std::sqrt(2.0));
677  B(16,0) = -1/(2*std::sqrt(2.0));
678  B(16,1) = 0;
679  B(16,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
680  B(17,0) = std::sqrt(3.0)/(2*std::sqrt(2.0));
681  B(17,1) = 0;
682  B(17,2) = 1/(2*std::sqrt(2.0));//B_3
683  B(18,0) = 0;
684  B(18,1) = 1/std::sqrt(2.0);
685  B(18,2) = 0;
686  B(19,0) = 1/std::sqrt(2.0);
687  B(19,1) = 0;
688  B(19,2) = 0;
689  B(20,0) = 0;
690  B(20,1) = std::sqrt(3.0)/(2*std::sqrt(2.0));
691  B(20,2) = -1/(2*std::sqrt(2.0));
692  B(21,0) = 0;
693  B(21,1) = -1/(2*std::sqrt(2.0));
694  B(21,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
695  B(22,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
696  B(22,1) = 0;
697  B(22,2) = -1/(2*std::sqrt(2.0));
698  B(23,0) = -1/(2*std::sqrt(2.0));
699  B(23,1) = 0;
700  B(23,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));//B_4
701  B(24,0) = 1/std::sqrt(2.0);
702  B(24,1) = 0;
703  B(24,2) = 0;
704  B(25,0) = 0;
705  B(25,1) = -1/std::sqrt(2.0);
706  B(25,2) = 0;
707  B(26,0) = 0;
708  B(26,1) = -1/(2*std::sqrt(2.0));
709  B(26,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
710  B(27,0) = 0;
711  B(27,1) = std::sqrt(3.0)/(2*std::sqrt(2.0));
712  B(27,2) = 1/(2*std::sqrt(2.0));
713  B(28,0) = -1/(2*std::sqrt(2.0));
714  B(28,1) = 0;
715  B(28,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
716  B(29,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
717  B(29,1) = 0;
718  B(29,2) = 1/(2*std::sqrt(2.0));//B_5
719  B(30,0) = 0;
720  B(30,1) = 1/std::sqrt(2.0);
721  B(30,2) = 0;
722  B(31,0) = 1/std::sqrt(2.0);
723  B(31,1) = 0;
724  B(31,2) = 0;
725  B(32,0) = 0;
726  B(32,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
727  B(32,2) = -1/(2*std::sqrt(2.0));
728  B(33,0) = 0;
729  B(33,1) = -1/(2*std::sqrt(2.0));
730  B(33,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
731  B(34,0) = std::sqrt(3.0)/(2*std::sqrt(2.0));
732  B(34,1) = 0;
733  B(34,2) = -1/(2*std::sqrt(2.0));
734  B(35,0) = -1/(2*std::sqrt(2.0));
735  B(35,1) = 0;
736  B(35,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));//B_6
737  }
738  else
739  std::cout << "STC::LDcode: unknown code name. Available codes are: V-BLAST_MxN, imp_V-BLAST_MxN, Alamouti_2xN, \
740  Switched_Alamouti_4xN, Double_Alamouti_4xN, Jafarkhani_4xN, Golden_2x2, Damen_2x2, 34ortho_3xN, 36LD_3xN, 37LD_3xN, 39LD_3xN" << std::endl;
741 }
742 
743 itpp::cmat STC::Hassibi_encode(const itpp::cvec &symb)
744 //LD code generation (symb_block symbols go to an channel_uses x em_antennas matrix) following Hassibi's approach
745 {
746  int nb_subblocks = symb.length()/symb_block;
747  int tx_duration = channel_uses*nb_subblocks;
748  itpp::cmat S(tx_duration,em_antennas);
749  itpp::cmat temp(channel_uses,em_antennas);
750  std::complex<double> j(0,1);
751  register int ns,k;
752  for (ns=0; ns<nb_subblocks; ns++)//encode block by block (symb_block symbols)
753  {
754  temp.zeros();
755  for (k=0; k<symb_block; k++)//sum over all symb_block matrices
756  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())\
757  +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()));
758  S.set_submatrix(ns*channel_uses, 0, temp);
759  }
760  return S;
761 }
762 
763 inline itpp::cmat STC::diag_pow(const itpp::cmat &in_mat, const double &in_exp)
764 //first input should be a diagonal square matrix with complex elements
765 {
766  register int n;
767  int dim = in_mat.rows();
768  itpp::cmat out_mat(dim,dim);
769  for (n=0; n<dim; n++)
770  out_mat(n,n) = std::pow(in_mat(n,n), in_exp);
771  return out_mat;
772 }
773 
774 inline itpp::mat STC::mat_pow(const itpp::mat &in_mat, const int &in_exp)
775 //square matrix power of integer exponent
776 {
777  if (in_exp==0)
778  return itpp::eye(in_mat.rows());
779  itpp::mat out = in_mat;
780  int abs_in_exp = std::abs(in_exp);
781  register int n;
782  for (n=1; n<abs_in_exp; n++)
783  out *= in_mat;
784  return (in_exp>0)?out:itpp::inv(out);
785 }
786 
787 }
SourceForge Logo

Generated on Fri Mar 21 2014 17:14:13 for IT++ by Doxygen 1.8.1.2