IT++ Logo
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 #include <itpp/itexports.h>
34 
35 namespace itpp
36 {
37 
71 class ITPP_EXPORT SISO
72 {
73 public:
75 
82  SISO();
84 
93  void set_map_metric(const std::string &in_MAP_metric);
95 
98  void set_precoder_generator(const itpp::bvec &in_prec_gen);
99  void set_precoder_generator(const int &in_prec_gen, const int &constraint_length);
101 
104  void set_generators(const itpp::bmat &in_gen);
105  void set_generators(const itpp::ivec &in_gen, const int &constraint_length);
107 
111  void set_tail(const bool &in_tail);
113  void set_viterbi_win_len(const int &win_len);
115  void set_sova_scaling_factor(const double &scaling_factor);
117  void set_sova_threshold(const double &threshold);
119  void set_viterbi_scaling_factors(const double &matching_scaling_factor,
120  const double &nonmatching_scaling_factor
121  );
123  void set_viterbi_hard_output_flag(const bool &flag);
124  //channel setup functions
126  void set_noise(const double &in_sigma2);
128 
130  void set_impulse_response(const itpp::vec &h);
132 
134  void set_impulse_response(const itpp::mat &H);
136 
138  void set_impulse_response(const itpp::cvec &h);
140 
161  void set_impulse_response(const itpp::cmat &cH);
163 
167  void set_scrambler_pattern(const itpp::vec &phi);
168  void set_scrambler_pattern(const itpp::bvec &phi);
170 
175  void set_mud_method(const std::string &method);
176  //demodulator and MIMO demapper setup
178 
182  void set_constellation(const int &in_nb_bits_symb,
183  const itpp::cvec &in_constellation,
184  const itpp::bmat &in_bin_constellation
185  );
186  void set_constellation(const int &in_nb_bits_symb,
187  const itpp::cvec &in_constellation,
188  const itpp::ivec &in_int_constellation
189  );
191 
193  void set_st_block_code(const int &Q,
194  const itpp::cmat &A,
195  const itpp::cmat &B,
196  const int &N
197  );
199 
209  void set_demapper_method(const std::string &method);
211  void rsc(itpp::vec &extrinsic_coded,
212  itpp::vec &extrinsic_data,
213  const itpp::vec &intrinsic_coded,
214  const itpp::vec &apriori_data
215  );
217  void rsc(itpp::vec &extrinsic_coded,
218  itpp::vec &extrinsic_data,
219  const itpp::vec &intrinsic_coded,
220  const itpp::vec &apriori_data,
221  const bool &tail
222  );
224  void nsc(itpp::vec &extrinsic_coded,
225  itpp::vec &extrinsic_data,
226  const itpp::vec &intrinsic_coded,
227  const itpp::vec &apriori_data
228  );
230  void nsc(itpp::vec &extrinsic_coded,
231  itpp::vec &extrinsic_data,
232  const itpp::vec &intrinsic_coded,
233  const itpp::vec &apriori_data,
234  const bool &tail
235  );
237 
240  void equalizer(itpp::vec &extrinsic_data,
241  const itpp::vec &rec_sig,
242  const itpp::vec &apriori_data
243  );
245 
248  void equalizer(itpp::vec &extrinsic_data,
249  const itpp::vec &rec_sig,
250  const itpp::vec &apriori_data,
251  const bool &tail
252  );
254  void descrambler(itpp::vec &extrinsic_coded,
255  itpp::vec &extrinsic_data,
256  const itpp::vec &intrinsic_coded,
257  const itpp::vec &apriori_data
258  );
260  void mud(itpp::mat &extrinsic_data,
261  const itpp::vec &rec_sig,
262  const itpp::mat &apriori_data
263  );
265  void demapper(itpp::vec &extrinsic_data,
266  const itpp::cvec &rec_sig,
267  const itpp::vec &apriori_data
268  );
270  void demapper(itpp::vec &extrinsic_data,
271  const itpp::cmat &rec_sig,
272  const itpp::vec &apriori_data
273  );
275  static double threshold(const double &x, const double &value);
276  static itpp::vec threshold(const itpp::vec &in, const double &value);
277  static itpp::mat threshold(const itpp::mat &in, const double &value);
278 private:
280  void rsc_logMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
281  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data);
283  void rsc_maxlogMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
284  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data);
286  void rsc_sova(itpp::vec &extrinsic_data,
287  const itpp::vec &intrinsic_coded,
288  const itpp::vec &apriori_data,
289  const int &win_len
290  );
292  void rsc_viterbi(itpp::vec &extrinsic_coded,
293  itpp::vec &extrinsic_data,
294  const itpp::vec &intrinsic_coded,
295  const itpp::vec &apriori_data,
296  const int &win_len
297  );
299  void nsc_logMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
300  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data);
302  void nsc_maxlogMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
303  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data);
305  void equalizer_logMAP(itpp::vec &extrinsic_data, const itpp::vec &rec_sig,
306  const itpp::vec &apriori_data);
308  void equalizer_maxlogMAP(itpp::vec &extrinsic_data, const itpp::vec &rec_sig,
309  const itpp::vec &apriori_data);
311  void mud_maxlogMAP(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
312  const itpp::mat &apriori_data);
314  void mud_maxlogTMAP(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
315  const itpp::mat &apriori_data, const double &threshold=-5);
317  void GCD(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
318  const itpp::mat &apriori_data);
320  void sGCD(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
321  const itpp::mat &apriori_data);
323  void Hassibi_maxlogMAP(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
324  const itpp::vec &apriori_data);
326  void GA(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
327  const itpp::vec &apriori_data);
329  void sGA(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
330  const itpp::vec &apriori_data);
332  void mmsePIC(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
333  const itpp::vec &apriori_data);
335  void zfPIC(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
336  const itpp::vec &apriori_data);
338  void Alamouti_maxlogMAP(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
339  const itpp::vec &apriori_data);
341  void demodulator_logMAP(itpp::vec &extrinsic_data, const itpp::cvec &rec_sig,
342  const itpp::vec &apriori_data);
344  void demodulator_maxlogMAP(itpp::vec &extrinsic_data, const itpp::cvec &rec_sig,
345  const itpp::vec &apriori_data);
347 
350  void print_err_msg(const std::string &msg) const;
351 
352  // MAP algorithm variables
354  struct ITPP_EXPORT MAP_Metrics
355  {
356  enum Type {Unknown, logMAP, maxlogMAP, SOVA, Viterbi};
357  MAP_Metrics() : _t(Unknown) {}
358  MAP_Metrics(Type t) : _t(t) {}
359  operator Type () const {return _t;}
360  private:
361  Type _t;
362  template<typename T> operator T () const;
363  };
364  MAP_Metrics MAP_metric;
366  itpp::bmat gen;
368  itpp::bvec prec_gen;
370  bool tail;
371  // SOVA & Viterbi variables
373  int Viterbi_win_len;
375  double SOVA_scaling_factor;
377  double SOVA_threshold;
379  double Viterbi_scaling_factor[2];
381  bool Viterbi_hard_output_flag;
382  //channel variables
384  double sigma2;
386  itpp::mat impulse_response;
388  itpp::cmat c_impulse_response;
390  itpp::bvec scrambler_pattern;
392  struct ITPP_EXPORT MUD_Methods
393  {
394  enum Type {Unknown, sGCD, maxlogMAP, GCD};
395  MUD_Methods() : _t(Unknown) {}
396  MUD_Methods(Type t) : _t(t) {}
397  operator Type () const {return _t;}
398  private:
399  Type _t;
400  template<typename T> operator T () const;
401  };
402  MUD_Methods MUD_method;
403  //constellation variables
405  int nb_bits_symb;
407  itpp::cvec constellation;
409  itpp::bmat bin_constellation;
410  //Space Time block code variables
412  int symbols_block;
414  int nb_em_ant;
416  int nb_rec_ant;
418  int block_duration;
420  itpp::cmat ST_gen1;
422  itpp::cmat ST_gen2;
424  struct ITPP_EXPORT Demapper_Methods
425  {
426  enum Type {Unknown, GA, Hassibi_maxlogMAP, sGA, mmsePIC, zfPIC, Alamouti_maxlogMAP};
427  Demapper_Methods() : _t(Unknown) {}
428  Demapper_Methods(Type t) : _t(t) {}
429  operator Type () const {return _t;}
430  private:
431  Type _t;
432  template<typename T> operator T () const;
433  };
434  Demapper_Methods demapper_method;
435 
436  //internal variables and functions
438  void zpFIRfilter(itpp::vec& filt,
439  const itpp::vec &h,
440  const itpp::vec &sig
441  );
443  void gen_chtrellis(void);
445  void gen_hyperTrellis(void);
447  struct
448  {
450  int stateNb;
451  int* prevState;
452  int* nextState;
453  double* output;
454  int* input;
455  } chtrellis;
457  void gen_rsctrellis(void);
459  struct
460  {
464  double* PARout;
465  itpp::bin* fm;
466  } rsctrellis;
468  void gen_nsctrellis(void);
470  struct
471  {
472  int stateNb;
473  int* prevState;
474  int* nextState;
475  double* output;
476  int* input;
477  } nsctrellis;
479  void find_half_const(int &select_half, itpp::vec &re_part,
480  itpp::bmat &re_bin_part, itpp::vec &im_part, itpp::bmat &im_bin_part);
482  void EquivRecSig(itpp::vec &x_eq, const itpp::cmat &rec_sig);
484  void EquivCh(itpp::mat &H_eq, const itpp::cvec &H);
486  void compute_symb_stats(itpp::vec &Es, itpp::vec &Vs,
487  int ns, int select_half, const itpp::vec &apriori_data,
488  const itpp::vec &re_part, const itpp::vec &im_part,
489  const itpp::bmat &re_bin_part, const itpp::bmat &im_bin_part);
490  static MAP_Metrics map_metric_from_string(const std::string &in_MAP_metric);
491  static MUD_Methods mud_method_from_string(const std::string &in_mud_method);
492  static Demapper_Methods demapper_method_from_string(const std::string &in_dem_method);
493 };
494 
495 inline SISO::SISO()
496 {
497  tail = false;
498  MAP_metric = MAP_Metrics::maxlogMAP;
499  MUD_method = MUD_Methods::sGCD;
500  scrambler_pattern = "0";//corresponds to +1 using BPSK mapping
501  prec_gen = "1";
502  demapper_method = Demapper_Methods::GA;
503  Viterbi_win_len = 20;//should be set according to the generator polynomials
504  SOVA_scaling_factor = 0.8;//set according to Wang [2003]
505  SOVA_threshold = 10;//according to Wang [2003] an adaptive value should be used
506  Viterbi_scaling_factor[0] = 1.4;//according to Kerner [2009]
507  Viterbi_scaling_factor[1] = 0.4;
508  Viterbi_hard_output_flag = false;
509 }
510 
511 inline SISO::MAP_Metrics SISO::map_metric_from_string(const std::string &in_MAP_metric)
512 {
513  if (in_MAP_metric=="logMAP")
514  {
515  return MAP_Metrics::logMAP;
516  } else if (in_MAP_metric=="maxlogMAP")
517  {
518  return MAP_Metrics::maxlogMAP;
519  } else if (in_MAP_metric=="SOVA")
520  {
521  return MAP_Metrics::SOVA;
522  } else if (in_MAP_metric=="Viterbi")
523  {
524  return MAP_Metrics::Viterbi;
525  } else
526  {
527  return MAP_Metrics::Unknown;
528  }
529 }
530 
531 inline SISO::MUD_Methods SISO::mud_method_from_string(const std::string &in_mud_method)
532 {
533  if (in_mud_method=="maxlogMAP")
534  {
535  return MUD_Methods::maxlogMAP;
536  } else if (in_mud_method=="sGCD")
537  {
538  return MUD_Methods::sGCD;
539  } else if (in_mud_method=="GCD")
540  {
541  return MUD_Methods::GCD;
542  } else
543  {
544  return MUD_Methods::Unknown;
545  }
546 }
547 
548 inline SISO::Demapper_Methods SISO::demapper_method_from_string(const std::string &in_dem_method)
549 {
550  if (in_dem_method=="Hassibi_maxlogMAP")
551  {
552  return Demapper_Methods::Hassibi_maxlogMAP;
553  } else if (in_dem_method=="Alamouti_maxlogMAP")
554  {
555  return Demapper_Methods::Alamouti_maxlogMAP;
556  } else if (in_dem_method=="GA")
557  {
558  return Demapper_Methods::GA;
559  } else if (in_dem_method=="sGA")
560  {
561  return Demapper_Methods::sGA;
562  } else if (in_dem_method=="mmsePIC")
563  {
564  return Demapper_Methods::mmsePIC;
565  } else if (in_dem_method=="zfPIC")
566  {
567  return Demapper_Methods::zfPIC;
568  } else
569  {
570  return Demapper_Methods::Unknown;
571  }
572 }
573 
574 inline void SISO::set_map_metric(const std::string &in_MAP_metric)
575 {
576  MAP_metric = map_metric_from_string(in_MAP_metric);
577 }
578 
579 inline void SISO::set_precoder_generator(const itpp::bvec &in_prec_gen)//set precoder polynomial
580 {
581  prec_gen = in_prec_gen;
582 }
583 
584 inline void SISO::set_precoder_generator(const int &in_prec_gen,
585  const int &constraint_length)//set precoder polynomial
586 {
587  prec_gen = itpp::dec2bin(constraint_length, in_prec_gen);
588 }
589 
590 inline void SISO::set_generators(const itpp::bmat &in_gen)
591 {
592  gen = in_gen;
593 }
594 
595 inline void SISO::set_generators(const itpp::ivec &in_gen,
596  const int &constraint_length)
597 {
598  int nb_outputs = in_gen.length();
599  gen.set_size(nb_outputs, constraint_length);
600  for (int n=0; n<nb_outputs; n++)
601  gen.set_row(n, itpp::dec2bin(constraint_length, in_gen(n)));
602 }
603 
604 inline void SISO::set_tail(const bool &in_tail)
605 {
606  tail = in_tail;
607 }
608 
609 inline void SISO::set_viterbi_win_len(const int &win_len)
610 {
611  Viterbi_win_len = win_len;
612 }
613 
614 inline void SISO::set_sova_scaling_factor(const double &scaling_factor)
615 {
616  SOVA_scaling_factor = scaling_factor;
617 }
618 
619 inline void SISO::set_sova_threshold(const double &threshold)
620 {
621  SOVA_threshold = threshold;
622 }
623 
624 inline void SISO::set_viterbi_scaling_factors(const double &matching_scaling_factor,
625  const double &nonmatching_scaling_factor)
626 {
627  Viterbi_scaling_factor[0] = matching_scaling_factor;
628  Viterbi_scaling_factor[1] = nonmatching_scaling_factor;
629 }
630 
631 inline void SISO::set_viterbi_hard_output_flag(const bool &flag)
632 {
633  Viterbi_hard_output_flag = flag;
634 }
635 
636 inline void SISO::set_noise(const double &in_sigma2)
637 {
638  sigma2 = in_sigma2;
639 }
640 
641 inline void SISO::set_impulse_response(const itpp::vec &h)
642 {
643  impulse_response.set_size(1, h.length());
644  impulse_response.set_row(0, h);
645 }
646 
647 inline void SISO::set_impulse_response(const itpp::mat &H)
648 {
649  impulse_response = H;
650 }
651 
652 inline void SISO::set_impulse_response(const itpp::cvec &h)
653 {
654  c_impulse_response.set_size(1, h.length());
655  c_impulse_response.set_row(0, h);
656 }
657 
658 inline void SISO::set_impulse_response(const itpp::cmat &cH)
659 {
660  c_impulse_response = cH;
661 }
662 
663 inline void SISO::set_scrambler_pattern(const itpp::vec &phi)
664 {
665  int phi_len = phi.length();
666  scrambler_pattern.set_size(phi_len);
667  //scrambler_pattern = to_bvec((1-phi)/2);//BPSK mapping: 0->+1 and 1->-1
668  register int n;
669  for (n=0; n<phi_len; n++)
670  scrambler_pattern(n) = itpp::bin((1-int(phi(n)))/2);//BPSK mapping: 0->+1 and 1->-1
671 }
672 
673 inline void SISO::set_scrambler_pattern(const itpp::bvec &phi)
674 {
675  scrambler_pattern = phi;
676 }
677 
678 inline void SISO::set_mud_method(const std::string &method)
679 {
680  MUD_method = mud_method_from_string(method);
681 }
682 
683 inline void SISO::set_constellation(const int &in_nb_bits_symb,
684  const itpp::cvec &in_constellation, const itpp::bmat &in_bin_constellation)
685 {
686  nb_bits_symb = in_nb_bits_symb;
687  constellation = in_constellation;
688  bin_constellation = in_bin_constellation;
689 }
690 
691 inline void SISO::set_constellation(const int &in_nb_bits_symb,
692  const itpp::cvec &in_constellation, const itpp::ivec &in_int_constellation)
693 {
694  nb_bits_symb = in_nb_bits_symb;
695  int nb_symb = in_constellation.length();
696  constellation.set_size(nb_symb);
697  bin_constellation.set_size(nb_symb, nb_bits_symb);
698  for (int n=0; n<nb_symb; n++)
699  {
700  constellation(n) = in_constellation(in_int_constellation(n));
701  bin_constellation.set_row(n, itpp::dec2bin(nb_bits_symb, n));
702  }
703 }
704 
705 inline void SISO::set_st_block_code(const int &Q, const itpp::cmat &A,
706  const itpp::cmat &B, const int &N)
707 {
708  symbols_block = Q;
709  nb_em_ant = A.cols();
710  nb_rec_ant = N;
711  block_duration = A.rows()/Q;
712  ST_gen1 = A;
713  ST_gen2 = B;
714 }
715 
716 inline void SISO::set_demapper_method(const std::string &method)
717 {
718  demapper_method = demapper_method_from_string(method);
719 }
720 
721 inline void SISO::rsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
722  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data, const bool &tail)
723 {
724  set_tail(tail);
725  rsc(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
726 }
727 
728 inline void SISO::rsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
729  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data)
730 {
731  if (gen.size()==0)
732  {
733  print_err_msg("SISO::rsc: generator polynomials not initialized");
734  return;
735  }
736 
737  if (MAP_metric==MAP_Metrics::logMAP)
738  {
739  rsc_logMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
740  } else if (MAP_metric==MAP_Metrics::maxlogMAP)
741  {
742  rsc_maxlogMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
743  } else if (MAP_metric==MAP_Metrics::SOVA)
744  {
745  //no extrinsic information for coded bits is provided
746  rsc_sova(extrinsic_data, intrinsic_coded, apriori_data, Viterbi_win_len);
747  } else if (MAP_metric==MAP_Metrics::Viterbi)
748  {
749  rsc_viterbi(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data, Viterbi_win_len);
750  } else
751  {
752  print_err_msg("SISO::rsc: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP or SOVA or Viterbi");
753  }
754 }
755 
756 inline void SISO::nsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
757  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data, const bool &tail)
758 {
759  set_tail(tail);
760  nsc(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
761 }
762 
763 inline void SISO::nsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
764  const itpp::vec &intrinsic_coded, const itpp::vec &apriori_data)
765 {
766  if (gen.size()==0)
767  {
768  print_err_msg("SISO::nsc: generator polynomials not initialized");
769  return;
770  }
771 
772  if (MAP_metric==MAP_Metrics::logMAP)
773  nsc_logMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
774  else if (MAP_metric==MAP_Metrics::maxlogMAP)
775  nsc_maxlogMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
776  else
777  print_err_msg("SISO::nsc: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP");
778 }
779 
780 inline void SISO::equalizer(itpp::vec &extrinsic_data,
781  const itpp::vec &rec_sig,
782  const itpp::vec &apriori_data,
783  const bool &tail
784  )
785 {
786  set_tail(tail);
787  equalizer(extrinsic_data, rec_sig, apriori_data);
788 }
789 
790 inline void SISO::equalizer(itpp::vec &extrinsic_data, const itpp::vec &rec_sig,
791  const itpp::vec &apriori_data)
792 {
793  if (impulse_response.size()==0)
794  {
795  print_err_msg("SISO::equalizer: channel impulse response not initialized");
796  return;
797  }
798  if ((impulse_response.size()==1)&&(prec_gen.length()==1))
799  {
800  print_err_msg("SISO::equalizer: flat fading channel and no precoder. Use the soft output of the channel (no need for a priori information)");
801  return;
802  }
803 
804  if (MAP_metric==MAP_Metrics::logMAP)
805  equalizer_logMAP(extrinsic_data, rec_sig, apriori_data);
806  else if (MAP_metric==MAP_Metrics::maxlogMAP)
807  equalizer_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
808  else
809  print_err_msg("SISO::equalizer: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP");
810 }
811 
812 inline void SISO::mud(itpp::mat &extrinsic_data, const itpp::vec &rec_sig,
813  const itpp::mat &apriori_data)
814 {
815  if (impulse_response.size()==0)
816  {
817  print_err_msg("SISO::mud: channel impulse response not initialized");
818  return;
819  }
820  if (impulse_response.rows()!=apriori_data.rows())
821  {
822  print_err_msg("SISO::mud: channel impulse response must have the same number of rows as a priori info.");
823  return;
824  }
825 
826  if (MUD_method==MUD_Methods::maxlogMAP)
827  mud_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
828  else if (MUD_method==MUD_Methods::GCD)
829  GCD(extrinsic_data, rec_sig, apriori_data);
830  else if (MUD_method==MUD_Methods::sGCD)
831  sGCD(extrinsic_data, rec_sig, apriori_data);
832  else
833  print_err_msg("SISO::mud: unknown MUD method. The MUD method should be either maxlogMAP, GCD or sGCD");
834 }
835 
836 inline void SISO::demapper(itpp::vec &extrinsic_data, const itpp::cvec &rec_sig,
837  const itpp::vec &apriori_data)
838 {
839  if (c_impulse_response.size()==0)
840  {
841  print_err_msg("SISO::demapper: channel impulse response not initialized");
842  return;
843  }
844  if ((constellation.size()==0) || (bin_constellation.size()==0))
845  {
846  print_err_msg("SISO::demapper: constellation not initialized");
847  return;
848  }
849  if (MAP_metric==MAP_Metrics::logMAP)
850  demodulator_logMAP(extrinsic_data, rec_sig, apriori_data);
851  else if (MAP_metric==MAP_Metrics::maxlogMAP)
852  demodulator_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
853  else
854  print_err_msg("SISO::demapper: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP");
855 }
856 
857 inline void SISO::demapper(itpp::vec &extrinsic_data, const itpp::cmat &rec_sig,
858  const itpp::vec &apriori_data)
859 {
860  if (c_impulse_response.size()==0)
861  {
862  print_err_msg("SISO::demapper: channel impulse response not initialized");
863  return;
864  }
865  if ((ST_gen1.size()==0) || (ST_gen2.size()==0))
866  {
867  print_err_msg("SISO::demapper: Space-Time generator polynomials not initialized");
868  return;
869  }
870  if ((constellation.size()==0) || (bin_constellation.size()==0))
871  {
872  print_err_msg("SISO::demapper: constellation not initialized");
873  return;
874  }
875 
876  if (demapper_method==Demapper_Methods::Hassibi_maxlogMAP)
877  Hassibi_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
878  else if (demapper_method==Demapper_Methods::GA)
879  GA(extrinsic_data, rec_sig, apriori_data);
880  else if (demapper_method==Demapper_Methods::sGA)
881  sGA(extrinsic_data, rec_sig, apriori_data);
882  else if (demapper_method==Demapper_Methods::mmsePIC)
883  mmsePIC(extrinsic_data, rec_sig, apriori_data);
884  else if (demapper_method==Demapper_Methods::zfPIC)
885  zfPIC(extrinsic_data, rec_sig, apriori_data);
886  else if (demapper_method==Demapper_Methods::Alamouti_maxlogMAP)
887  Alamouti_maxlogMAP(extrinsic_data, rec_sig, apriori_data);
888  else
889  print_err_msg("SISO::demapper: unknown demapper method. The demapper method should be either Hassibi_maxlogMAP, GA, sGA, mmsePIC, zfPIC or Alamouti_maxlogMAP");
890 }
891 
892 inline void SISO::print_err_msg(const std::string &msg) const
893 {
894 #ifdef mex_h
895  mexErrMsgTxt(msg.c_str());
896 #else
897  std::cout << msg << std::endl;
898 #endif
899 }
900 
901 inline double SISO::threshold(const double &x, const double &value)
902 {
903  if ((x>value)||(x<-value))
904  return (x>0?value:-value);
905  return x;
906 }
907 
908 inline itpp::vec SISO::threshold(const itpp::vec &in, const double &value)
909 {
910  itpp::vec out(in.length());
911  register int n;
912  for (n=0; n<in.length(); n++)
913  out(n) = threshold(in(n), value);
914  return out;
915 }
916 
917 inline itpp::mat SISO::threshold(const itpp::mat &in, const double &value)
918 {
919  itpp::mat out(in.rows(),in.cols());
920  register int n;
921  for (n=0; n<in.rows(); n++)
922  out.set_row(n, threshold(in.get_row(n), value));
923  return out;
924 }
925 
926 }
927 
928 #endif /*SISO_H_*/
SourceForge Logo

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