IT++ Logo
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
siso.h
Go to the documentation of this file.
1 
29 #ifndef SISO_H
30 #define SISO_H
31 
32 #include <itpp/itbase.h> //IT++ base module
33 
34 namespace itpp
35 {
36 
53 class SISO
54 {
55 public:
57 
64  SISO();
66 
74  void set_map_metric(const std::string &in_MAP_metric);
76 
79  void set_precoder_generator(const itpp::bvec &in_prec_gen);
80  void set_precoder_generator(const int &in_prec_gen, const int &constraint_length);
82 
85  void set_generators(const itpp::bmat &in_gen);
86  void set_generators(const itpp::ivec &in_gen, const int &constraint_length);
88 
92  void set_tail(const bool &in_tail);
94  void set_viterbi_win_len(const int &win_len);
96  void set_sova_scaling_factor(const double &scaling_factor);
98  void set_sova_threshold(const double &threshold);
100  void set_viterbi_scaling_factors(const double &matching_scaling_factor,
101  const double &nonmatching_scaling_factor
102  );
104  void set_viterbi_hard_output_flag(const bool &flag);
105  //channel setup functions
107  void set_noise(const double &in_sigma2);
109 
111  void set_impulse_response(const itpp::vec &h);
113 
115  void set_impulse_response(const itpp::mat &H);
117 
119  void set_impulse_response(const itpp::cvec &h);
121 
142  void set_impulse_response(const itpp::cmat &cH);
144 
148  void set_scrambler_pattern(const itpp::vec &phi);
149  void set_scrambler_pattern(const itpp::bvec &phi);
151 
156  void set_mud_method(const std::string &method);
157  //demodulator and MIMO demapper setup
159 
161  void set_constellation(const int &in_nb_bits_symb,
162  const itpp::cvec &in_constellation,
163  const itpp::bmat &in_bin_constellation
164  );
165  void set_constellation(const int &in_nb_bits_symb,
166  const itpp::cvec &in_constellation,
167  const itpp::ivec &in_int_constellation
168  );
170 
172  void set_st_block_code(const int &Q,
173  const itpp::cmat &A,
174  const itpp::cmat &B,
175  const int &N
176  );
178 
188  void set_demapper_method(const std::string &method);
190  void rsc(itpp::vec &extrinsic_coded,
191  itpp::vec &extrinsic_data,
192  const itpp::vec &intrinsic_coded,
193  const itpp::vec &apriori_data
194  );
196  void rsc(itpp::vec &extrinsic_coded,
197  itpp::vec &extrinsic_data,
198  const itpp::vec &intrinsic_coded,
199  const itpp::vec &apriori_data,
200  const bool &tail
201  );
203  void nsc(itpp::vec &extrinsic_coded,
204  itpp::vec &extrinsic_data,
205  const itpp::vec &intrinsic_coded,
206  const itpp::vec &apriori_data
207  );
209  void nsc(itpp::vec &extrinsic_coded,
210  itpp::vec &extrinsic_data,
211  const itpp::vec &intrinsic_coded,
212  const itpp::vec &apriori_data,
213  const bool &tail
214  );
216 
219  void equalizer(itpp::vec &extrinsic_data,
220  const itpp::vec &rec_sig,
221  const itpp::vec &apriori_data
222  );
224 
227  void equalizer(itpp::vec &extrinsic_data,
228  const itpp::vec &rec_sig,
229  const itpp::vec &apriori_data,
230  const bool &tail
231  );
233  void descrambler(itpp::vec &extrinsic_coded,
234  itpp::vec &extrinsic_data,
235  const itpp::vec &intrinsic_coded,
236  const itpp::vec &apriori_data
237  );
239  void mud(itpp::mat &extrinsic_data,
240  const itpp::vec &rec_sig,
241  const itpp::mat &apriori_data
242  );
244  void demapper(itpp::vec &extrinsic_data,
245  const itpp::cvec &rec_sig,
246  const itpp::vec &apriori_data
247  );
249  void demapper(itpp::vec &extrinsic_data,
250  const itpp::cmat &rec_sig,
251  const itpp::vec &apriori_data
252  );
254  static double threshold(const double &x, const double &value);
255  static itpp::vec threshold(const itpp::vec &in, const double &value);
256  static itpp::mat threshold(const itpp::mat &in, const double &value);
257 private:
259  void rsc_logMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
260  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data);
262  void rsc_maxlogMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
263  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data);
265  void rsc_sova(itpp::vec &extrinsic_data,
266  const itpp::vec &intrinsic_coded,
267  const itpp::vec &apriori_data,
268  const int &win_len
269  );
271  void rsc_viterbi(itpp::vec &extrinsic_coded,
272  itpp::vec &extrinsic_data,
273  const itpp::vec &intrinsic_coded,
274  const itpp::vec &apriori_data,
275  const int &win_len
276  );
278  void nsc_logMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
279  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data);
281  void nsc_maxlogMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
282  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data);
284  void equalizer_logMAP(itpp::vec &extrinsic_data, const itpp::vec &rec_sig,
285  const itpp::vec &apriori_data);
287  void equalizer_maxlogMAP(itpp::vec &extrinsic_data, const itpp::vec &rec_sig,
288  const itpp::vec &apriori_data);
290  void mud_maxlogMAP(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
291  const itpp::mat &apriori_data);
293  void mud_maxlogTMAP(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
294  const itpp::mat &apriori_data, const double &threshold=-5);
296  void GCD(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
297  const itpp::mat &apriori_data);
299  void sGCD(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
300  const itpp::mat &apriori_data);
302  void Hassibi_maxlogMAP(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
303  const itpp::vec &apriori_data);
305  void GA(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
306  const itpp::vec &apriori_data);
308  void sGA(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
309  const itpp::vec &apriori_data);
311  void mmsePIC(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
312  const itpp::vec &apriori_data);
314  void zfPIC(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
315  const itpp::vec &apriori_data);
317  void Alamouti_maxlogMAP(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
318  const itpp::vec &apriori_data);
320  void demodulator_logMAP(itpp::vec &extrinsic_data, const itpp::cvec &rec_sig,
321  const itpp::vec &apriori_data);
323  void demodulator_maxlogMAP(itpp::vec &extrinsic_data, const itpp::cvec &rec_sig,
324  const itpp::vec &apriori_data);
326 
329  void print_err_msg(const std::string &msg) const;
330 
331  // MAP algorithm variables
333  std::string MAP_metric;
335  itpp::bmat gen;
337  itpp::bvec prec_gen;
339  bool tail;
340  // SOVA & Viterbi variables
342  int Viterbi_win_len;
344  double SOVA_scaling_factor;
346  double SOVA_threshold;
348  double Viterbi_scaling_factor[2];
350  bool Viterbi_hard_output_flag;
351  //channel variables
353  double sigma2;
355  itpp::mat impulse_response;
357  itpp::cmat c_impulse_response;
359  itpp::bvec scrambler_pattern;
361  std::string MUD_method;
362  //constellation variables
364  int nb_bits_symb;
366  itpp::cvec constellation;
368  itpp::bmat bin_constellation;
369  //Space Time block code variables
371  int symbols_block;
373  int nb_em_ant;
375  int nb_rec_ant;
377  int block_duration;
379  itpp::cmat ST_gen1;
381  itpp::cmat ST_gen2;
383  std::string demapper_method;
384 
385  //internal variables and functions
387  void zpFIRfilter(itpp::vec& filt,
388  const itpp::vec &h,
389  const itpp::vec &sig
390  );
392  void gen_chtrellis(void);
394  void gen_hyperTrellis(void);
396  struct
397  {
399  int stateNb;
400  int* prevState;
401  int* nextState;
402  double* output;
403  int* input;
404  } chtrellis;
406  void gen_rsctrellis(void);
408  struct
409  {
413  double* PARout;
414  itpp::bin* fm;
415  } rsctrellis;
417  void gen_nsctrellis(void);
419  struct
420  {
421  int stateNb;
422  int* prevState;
423  int* nextState;
424  double* output;
425  int* input;
426  } nsctrellis;
428  void find_half_const(int &select_half, itpp::vec &re_part,
429  itpp::bmat &re_bin_part, itpp::vec &im_part, itpp::bmat &im_bin_part);
431  void EquivRecSig(itpp::vec &x_eq, const itpp::cmat &rec_sig);
433  void EquivCh(itpp::mat &H_eq, const itpp::cvec &H);
434 };
435 
436 inline SISO::SISO()
437 {
438  tail = false;
439  MAP_metric = "maxlogMAP";
440  MUD_method = "sGCD";
441  scrambler_pattern = "0";//corresponds to +1 using BPSK mapping
442  prec_gen = "1";
443  demapper_method = "GA";
444  Viterbi_win_len = 20;//should be set according to the generator polynomials
445  SOVA_scaling_factor = 0.8;//set according to Wang [2003]
446  SOVA_threshold = 10;//according to Wang [2003] an adaptive value should be used
447  Viterbi_scaling_factor[0] = 1.4;//according to Kerner [2009]
448  Viterbi_scaling_factor[1] = 0.4;
449  Viterbi_hard_output_flag = false;
450 }
451 
452 inline void SISO::set_map_metric(const std::string &in_MAP_metric)
453 {
454  MAP_metric = in_MAP_metric;
455 }
456 
457 inline void SISO::set_precoder_generator(const itpp::bvec &in_prec_gen)//set precoder polynomial
458 {
459  prec_gen = in_prec_gen;
460 }
461 
462 inline void SISO::set_precoder_generator(const int &in_prec_gen,
463  const int &constraint_length)//set precoder polynomial
464 {
465  prec_gen = itpp::dec2bin(constraint_length, in_prec_gen);
466 }
467 
468 inline void SISO::set_generators(const itpp::bmat &in_gen)
469 {
470  gen = in_gen;
471 }
472 
473 inline void SISO::set_generators(const itpp::ivec &in_gen,
474  const int &constraint_length)
475 {
476  int nb_outputs = in_gen.length();
477  gen.set_size(nb_outputs, constraint_length);
478  for (int n=0; n<nb_outputs; n++)
479  gen.set_row(n, itpp::dec2bin(constraint_length, in_gen(n)));
480 }
481 
482 inline void SISO::set_tail(const bool &in_tail)
483 {
484  tail = in_tail;
485 }
486 
487 inline void SISO::set_viterbi_win_len(const int &win_len)
488 {
489  Viterbi_win_len = win_len;
490 }
491 
492 inline void SISO::set_sova_scaling_factor(const double &scaling_factor)
493 {
494  SOVA_scaling_factor = scaling_factor;
495 }
496 
497 inline void SISO::set_sova_threshold(const double &threshold)
498 {
499  SOVA_threshold = threshold;
500 }
501 
502 inline void SISO::set_viterbi_scaling_factors(const double &matching_scaling_factor,
503  const double &nonmatching_scaling_factor)
504 {
505  Viterbi_scaling_factor[0] = matching_scaling_factor;
506  Viterbi_scaling_factor[1] = nonmatching_scaling_factor;
507 }
508 
509 inline void SISO::set_viterbi_hard_output_flag(const bool &flag)
510 {
511  Viterbi_hard_output_flag = flag;
512 }
513 
514 inline void SISO::set_noise(const double &in_sigma2)
515 {
516  sigma2 = in_sigma2;
517 }
518 
519 inline void SISO::set_impulse_response(const itpp::vec &h)
520 {
521  impulse_response.set_size(1, h.length());
522  impulse_response.set_row(0, h);
523 }
524 
525 inline void SISO::set_impulse_response(const itpp::mat &H)
526 {
527  impulse_response = H;
528 }
529 
530 inline void SISO::set_impulse_response(const itpp::cvec &h)
531 {
532  c_impulse_response.set_size(1, h.length());
533  c_impulse_response.set_row(0, h);
534 }
535 
536 inline void SISO::set_impulse_response(const itpp::cmat &cH)
537 {
538  c_impulse_response = cH;
539 }
540 
541 inline void SISO::set_scrambler_pattern(const itpp::vec &phi)
542 {
543  int phi_len = phi.length();
544  scrambler_pattern.set_size(phi_len);
545  //scrambler_pattern = to_bvec((1-phi)/2);//BPSK mapping: 0->+1 and 1->-1
546  register int n;
547  for (n=0; n<phi_len; n++)
548  scrambler_pattern(n) = itpp::bin((1-int(phi(n)))/2);//BPSK mapping: 0->+1 and 1->-1
549 }
550 
551 inline void SISO::set_scrambler_pattern(const itpp::bvec &phi)
552 {
553  scrambler_pattern = phi;
554 }
555 
556 inline void SISO::set_mud_method(const std::string &method)
557 {
558  MUD_method = method;
559 }
560 
561 inline void SISO::set_constellation(const int &in_nb_bits_symb,
562  const itpp::cvec &in_constellation, const itpp::bmat &in_bin_constellation)
563 {
564  nb_bits_symb = in_nb_bits_symb;
565  constellation = in_constellation;
566  bin_constellation = in_bin_constellation;
567 }
568 
569 inline void SISO::set_constellation(const int &in_nb_bits_symb,
570  const itpp::cvec &in_constellation, const itpp::ivec &in_int_constellation)
571 {
572  nb_bits_symb = in_nb_bits_symb;
573  int nb_symb = in_constellation.length();
574  constellation.set_size(nb_symb);
575  bin_constellation.set_size(nb_symb, nb_bits_symb);
576  for (int n=0; n<nb_symb; n++)
577  {
578  constellation(n) = in_constellation(in_int_constellation(n));
579  bin_constellation.set_row(n, itpp::dec2bin(nb_bits_symb, n));
580  }
581 }
582 
583 inline void SISO::set_st_block_code(const int &Q, const itpp::cmat &A,
584  const itpp::cmat &B, const int &N)
585 {
586  symbols_block = Q;
587  nb_em_ant = A.cols();
588  nb_rec_ant = N;
589  block_duration = A.rows()/Q;
590  ST_gen1 = A;
591  ST_gen2 = B;
592 }
593 
594 inline void SISO::set_demapper_method(const std::string &method)
595 {
596  demapper_method = method;
597 }
598 
599 inline void SISO::rsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
600  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data, const bool &tail)
601 {
602  set_tail(tail);
603  rsc(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
604 }
605 
606 inline void SISO::rsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
607  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data)
608 {
609  if (gen.size()==0)
610  {
611  print_err_msg("SISO::rsc: generator polynomials not initialized");
612  return;
613  }
614 
615  if (MAP_metric=="logMAP")
616  {
617  rsc_logMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
618  } else if (MAP_metric=="maxlogMAP")
619  {
620  rsc_maxlogMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
621  } else if (MAP_metric=="SOVA")
622  {
623  //no extrinsic information for coded bits is provided
624  rsc_sova(extrinsic_data, intrinsic_coded, apriori_data, Viterbi_win_len);
625  } else if (MAP_metric=="Viterbi")
626  {
627  rsc_viterbi(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data, Viterbi_win_len);
628  } else
629  {
630  print_err_msg("SISO::rsc: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP or SOVA or Viterbi");
631  }
632 }
633 
634 inline void SISO::nsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
635  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data, const bool &tail)
636 {
637  set_tail(tail);
638  nsc(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
639 }
640 
641 inline void SISO::nsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
642  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data)
643 {
644  if (gen.size()==0)
645  {
646  print_err_msg("SISO::nsc: generator polynomials not initialized");
647  return;
648  }
649 
650  if (MAP_metric=="logMAP")
651  nsc_logMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
652  else if (MAP_metric=="maxlogMAP")
653  nsc_maxlogMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
654  else
655  print_err_msg("SISO::nsc: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP");
656 }
657 
658 inline void SISO::equalizer(itpp::vec &extrinsic_data,
659  const itpp::vec &rec_sig,
660  const itpp::vec &apriori_data,
661  const bool &tail
662  )
663 {
664  set_tail(tail);
665  equalizer(extrinsic_data, rec_sig, apriori_data);
666 }
667 
668 inline void SISO::equalizer(itpp::vec &extrinsic_data, const itpp::vec &rec_sig,
669  const itpp::vec &apriori_data)
670 {
671  if (impulse_response.size()==0)
672  {
673  print_err_msg("SISO::equalizer: channel impulse response not initialized");
674  return;
675  }
676  if ((impulse_response.size()==1)&&(prec_gen.length()==1))
677  {
678  print_err_msg("SISO::equalizer: flat fading channel and no precoder. Use the soft output of the channel (no need for a priori information)");
679  return;
680  }
681 
682  if (MAP_metric=="logMAP")
683  equalizer_logMAP(extrinsic_data, rec_sig, apriori_data);
684  else if (MAP_metric=="maxlogMAP")
685  equalizer_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
686  else
687  print_err_msg("SISO::equalizer: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP");
688 }
689 
690 inline void SISO::mud(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
691  const itpp::mat &apriori_data)
692 {
693  if (impulse_response.size()==0)
694  {
695  print_err_msg("SISO::mud: channel impulse response not initialized");
696  return;
697  }
698  if (impulse_response.rows()!=apriori_data.rows())
699  {
700  print_err_msg("SISO::mud: channel impulse response must have the same number of rows as a priori info.");
701  return;
702  }
703 
704  if (MUD_method=="maxlogMAP")
705  mud_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
706  else if (MUD_method=="GCD")
707  GCD(extrinsic_data, rec_sig, apriori_data);
708  else if (MUD_method=="sGCD")
709  sGCD(extrinsic_data, rec_sig, apriori_data);
710  else
711  print_err_msg("SISO::mud: unknown MUD method. The MUD method should be either maxlogMAP, GCD or sGCD");
712 }
713 
714 inline void SISO::demapper(itpp::vec &extrinsic_data, const itpp::cvec &rec_sig,
715  const itpp::vec &apriori_data)
716 {
717  if (c_impulse_response.size()==0)
718  {
719  print_err_msg("SISO::demapper: channel impulse response not initialized");
720  return;
721  }
722  if ((constellation.size()==0) || (bin_constellation.size()==0))
723  {
724  print_err_msg("SISO::demapper: constellation not initialized");
725  return;
726  }
727  if (MAP_metric=="logMAP")
728  demodulator_logMAP(extrinsic_data, rec_sig, apriori_data);
729  else if (MAP_metric=="maxlogMAP")
730  demodulator_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
731  else
732  print_err_msg("SISO::demapper: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP");
733 }
734 
735 inline void SISO::demapper(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
736  const itpp::vec &apriori_data)
737 {
738  if (c_impulse_response.size()==0)
739  {
740  print_err_msg("SISO::demapper: channel impulse response not initialized");
741  return;
742  }
743  if ((ST_gen1.size()==0) || (ST_gen2.size()==0))
744  {
745  print_err_msg("SISO::demapper: Space-Time generator polynomials not initialized");
746  return;
747  }
748  if ((constellation.size()==0) || (bin_constellation.size()==0))
749  {
750  print_err_msg("SISO::demapper: constellation not initialized");
751  return;
752  }
753 
754  if (demapper_method=="Hassibi_maxlogMAP")
755  Hassibi_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
756  else if (demapper_method=="GA")
757  GA(extrinsic_data, rec_sig, apriori_data);
758  else if (demapper_method=="sGA")
759  sGA(extrinsic_data, rec_sig, apriori_data);
760  else if (demapper_method=="mmsePIC")
761  mmsePIC(extrinsic_data, rec_sig, apriori_data);
762  else if (demapper_method=="zfPIC")
763  zfPIC(extrinsic_data, rec_sig, apriori_data);
764  else if (demapper_method=="Alamouti_maxlogMAP")
765  Alamouti_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
766  else
767  print_err_msg("SISO::demapper: unknown demapper method. The demapper method should be either Hassibi_maxlogMAP, GA, sGA, mmsePIC, zfPIC or Alamouti_maxlogMAP");
768 }
769 
770 inline void SISO::print_err_msg(const std::string &msg) const
771 {
772 #ifdef mex_h
773  mexErrMsgTxt(msg.c_str());
774 #else
775  std::cout << msg << std::endl;
776 #endif
777 }
778 
779 inline double SISO::threshold(const double &x, const double &value)
780 {
781  if ((x>value)||(x<-value))
782  return (x>0?value:-value);
783  return x;
784 }
785 
786 inline itpp::vec SISO::threshold(const itpp::vec &in, const double &value)
787 {
788  itpp::vec out(in.length());
789  register int n;
790  for (n=0; n<in.length(); n++)
791  out(n) = threshold(in(n), value);
792  return out;
793 }
794 
795 inline itpp::mat SISO::threshold(const itpp::mat &in, const double &value)
796 {
797  itpp::mat out(in.rows(),in.cols());
798  register int n;
799  for (n=0; n<in.rows(); n++)
800  out.set_row(n, threshold(in.get_row(n), value));
801  return out;
802 }
803 
804 }
805 
806 #endif /*SISO_H_*/
SourceForge Logo

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