86 void set_generators(
const itpp::ivec &in_gen,
const int &constraint_length);
101 const double &nonmatching_scaling_factor
162 const itpp::cvec &in_constellation,
166 const itpp::cvec &in_constellation,
167 const itpp::ivec &in_int_constellation
190 void rsc(itpp::vec &extrinsic_coded,
191 itpp::vec &extrinsic_data,
192 const itpp::vec &intrinsic_coded,
193 const itpp::vec &apriori_data
196 void rsc(itpp::vec &extrinsic_coded,
197 itpp::vec &extrinsic_data,
198 const itpp::vec &intrinsic_coded,
199 const itpp::vec &apriori_data,
203 void nsc(itpp::vec &extrinsic_coded,
204 itpp::vec &extrinsic_data,
205 const itpp::vec &intrinsic_coded,
206 const itpp::vec &apriori_data
209 void nsc(itpp::vec &extrinsic_coded,
210 itpp::vec &extrinsic_data,
211 const itpp::vec &intrinsic_coded,
212 const itpp::vec &apriori_data,
219 void equalizer(itpp::vec &extrinsic_data,
220 const itpp::vec &rec_sig,
221 const itpp::vec &apriori_data
227 void equalizer(itpp::vec &extrinsic_data,
228 const itpp::vec &rec_sig,
229 const itpp::vec &apriori_data,
234 itpp::vec &extrinsic_data,
235 const itpp::vec &intrinsic_coded,
236 const itpp::vec &apriori_data
239 void mud(itpp::mat &extrinsic_data,
240 const itpp::vec &rec_sig,
241 const itpp::mat &apriori_data
244 void demapper(itpp::vec &extrinsic_data,
245 const itpp::cvec &rec_sig,
246 const itpp::vec &apriori_data
249 void demapper(itpp::vec &extrinsic_data,
250 const itpp::cmat &rec_sig,
251 const itpp::vec &apriori_data
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);
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,
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,
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);
329 void print_err_msg(
const std::string &msg)
const;
333 std::string MAP_metric;
344 double SOVA_scaling_factor;
346 double SOVA_threshold;
348 double Viterbi_scaling_factor[2];
350 bool Viterbi_hard_output_flag;
355 itpp::mat impulse_response;
357 itpp::cmat c_impulse_response;
359 itpp::bvec scrambler_pattern;
361 std::string MUD_method;
366 itpp::cvec constellation;
383 std::string demapper_method;
387 void zpFIRfilter(itpp::vec& filt,
392 void gen_chtrellis(
void);
394 void gen_hyperTrellis(
void);
406 void gen_rsctrellis(
void);
417 void gen_nsctrellis(
void);
428 void find_half_const(
int &select_half, itpp::vec &re_part,
431 void EquivRecSig(itpp::vec &x_eq,
const itpp::cmat &rec_sig);
433 void EquivCh(itpp::mat &H_eq,
const itpp::cvec &H);
439 MAP_metric =
"maxlogMAP";
441 scrambler_pattern =
"0";
443 demapper_method =
"GA";
444 Viterbi_win_len = 20;
445 SOVA_scaling_factor = 0.8;
447 Viterbi_scaling_factor[0] = 1.4;
448 Viterbi_scaling_factor[1] = 0.4;
449 Viterbi_hard_output_flag =
false;
454 MAP_metric = in_MAP_metric;
459 prec_gen = in_prec_gen;
463 const int &constraint_length)
474 const int &constraint_length)
476 int nb_outputs = in_gen.length();
477 gen.set_size(nb_outputs, constraint_length);
478 for (
int n=0; n<nb_outputs; n++)
489 Viterbi_win_len = win_len;
494 SOVA_scaling_factor = scaling_factor;
503 const double &nonmatching_scaling_factor)
505 Viterbi_scaling_factor[0] = matching_scaling_factor;
506 Viterbi_scaling_factor[1] = nonmatching_scaling_factor;
511 Viterbi_hard_output_flag = flag;
521 impulse_response.set_size(1, h.length());
522 impulse_response.set_row(0, h);
527 impulse_response = H;
532 c_impulse_response.set_size(1, h.length());
533 c_impulse_response.set_row(0, h);
538 c_impulse_response = cH;
543 int phi_len = phi.length();
544 scrambler_pattern.set_size(phi_len);
547 for (n=0; n<phi_len; n++)
548 scrambler_pattern(n) =
itpp::bin((1-
int(phi(n)))/2);
553 scrambler_pattern = phi;
562 const itpp::cvec &in_constellation,
const itpp::bmat &in_bin_constellation)
564 nb_bits_symb = in_nb_bits_symb;
565 constellation = in_constellation;
566 bin_constellation = in_bin_constellation;
570 const itpp::cvec &in_constellation,
const itpp::ivec &in_int_constellation)
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++)
578 constellation(n) = in_constellation(in_int_constellation(n));
579 bin_constellation.set_row(n,
itpp::dec2bin(nb_bits_symb, n));
584 const itpp::cmat &B,
const int &N)
587 nb_em_ant = A.cols();
589 block_duration = A.rows()/Q;
596 demapper_method = method;
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)
603 rsc(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
606 inline void SISO::rsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
607 const itpp::vec &intrinsic_coded,
const itpp::vec &apriori_data)
611 print_err_msg(
"SISO::rsc: generator polynomials not initialized");
615 if (MAP_metric==
"logMAP")
617 rsc_logMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
618 }
else if (MAP_metric==
"maxlogMAP")
620 rsc_maxlogMAP(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
621 }
else if (MAP_metric==
"SOVA")
624 rsc_sova(extrinsic_data, intrinsic_coded, apriori_data, Viterbi_win_len);
625 }
else if (MAP_metric==
"Viterbi")
627 rsc_viterbi(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data, Viterbi_win_len);
630 print_err_msg(
"SISO::rsc: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP or SOVA or Viterbi");
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)
638 nsc(extrinsic_coded, extrinsic_data, intrinsic_coded, apriori_data);
641 inline void SISO::nsc(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
642 const itpp::vec &intrinsic_coded,
const itpp::vec &apriori_data)
646 print_err_msg(
"SISO::nsc: generator polynomials not initialized");
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);
655 print_err_msg(
"SISO::nsc: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP");
659 const itpp::vec &rec_sig,
660 const itpp::vec &apriori_data,
665 equalizer(extrinsic_data, rec_sig, apriori_data);
669 const itpp::vec &apriori_data)
671 if (impulse_response.size()==0)
673 print_err_msg(
"SISO::equalizer: channel impulse response not initialized");
676 if ((impulse_response.size()==1)&&(prec_gen.length()==1))
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)");
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);
687 print_err_msg(
"SISO::equalizer: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP");
690 inline void SISO::mud(itpp::mat &extrinsic_data,
const itpp::vec &rec_sig,
691 const itpp::mat &apriori_data)
693 if (impulse_response.size()==0)
695 print_err_msg(
"SISO::mud: channel impulse response not initialized");
698 if (impulse_response.rows()!=apriori_data.rows())
700 print_err_msg(
"SISO::mud: channel impulse response must have the same number of rows as a priori info.");
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);
711 print_err_msg(
"SISO::mud: unknown MUD method. The MUD method should be either maxlogMAP, GCD or sGCD");
715 const itpp::vec &apriori_data)
717 if (c_impulse_response.size()==0)
719 print_err_msg(
"SISO::demapper: channel impulse response not initialized");
722 if ((constellation.size()==0) || (bin_constellation.size()==0))
724 print_err_msg(
"SISO::demapper: constellation not initialized");
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);
732 print_err_msg(
"SISO::demapper: unknown MAP metric. The MAP metric should be either logMAP or maxlogMAP");
736 const itpp::vec &apriori_data)
738 if (c_impulse_response.size()==0)
740 print_err_msg(
"SISO::demapper: channel impulse response not initialized");
743 if ((ST_gen1.size()==0) || (ST_gen2.size()==0))
745 print_err_msg(
"SISO::demapper: Space-Time generator polynomials not initialized");
748 if ((constellation.size()==0) || (bin_constellation.size()==0))
750 print_err_msg(
"SISO::demapper: constellation not initialized");
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);
767 print_err_msg(
"SISO::demapper: unknown demapper method. The demapper method should be either Hassibi_maxlogMAP, GA, sGA, mmsePIC, zfPIC or Alamouti_maxlogMAP");
770 inline void SISO::print_err_msg(
const std::string &msg)
const
773 mexErrMsgTxt(msg.c_str());
775 std::cout << msg << std::endl;
781 if ((x>value)||(x<-value))
782 return (x>0?value:-value);
786 inline itpp::vec
SISO::threshold(
const itpp::vec &in,
const double &value)
788 itpp::vec out(in.length());
790 for (n=0; n<in.length(); n++)
795 inline itpp::mat
SISO::threshold(
const itpp::mat &in,
const double &value)
797 itpp::mat out(in.rows(),in.cols());
799 for (n=0; n<in.rows(); n++)
800 out.set_row(n,
threshold(in.get_row(n), value));