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

Generated on Sat May 25 2013 16:32:22 for IT++ by Doxygen 1.8.2