00001 00029 #ifndef MODULATOR_H 00030 #define MODULATOR_H 00031 00032 #include <itpp/base/mat.h> 00033 #include <itpp/base/math/elem_math.h> 00034 #include <itpp/base/math/log_exp.h> 00035 #include <itpp/base/converters.h> 00036 #include <itpp/base/math/min_max.h> 00037 00038 00039 namespace itpp 00040 { 00041 00046 enum Soft_Method { 00047 LOGMAP, 00048 APPROX 00049 }; 00050 00073 template <typename T> 00074 class Modulator 00075 { 00076 public: 00078 Modulator(); 00080 Modulator(const Vec<T>& symbols, const ivec& bits2symbols); 00082 virtual ~Modulator() {} 00083 00085 virtual void set(const Vec<T>& symbols, const ivec& bits2symbols); 00086 00088 virtual int bits_per_symbol() const { return k; } 00090 virtual Vec<T> get_symbols() const { return symbols; } 00108 virtual ivec get_bits2symbols() const { return bits2symbols; } 00109 00111 virtual void modulate(const ivec& symbolnumbers, Vec<T>& output) const; 00113 virtual Vec<T> modulate(const ivec& symbolnumbers) const; 00114 00116 virtual void demodulate(const Vec<T>& signal, ivec& output) const; 00118 virtual ivec demodulate(const Vec<T>& signal) const; 00119 00121 virtual void modulate_bits(const bvec& bits, Vec<T>& output) const; 00123 virtual Vec<T> modulate_bits(const bvec& bits) const; 00124 00126 virtual void demodulate_bits(const Vec<T>& signal, bvec& bits) const; 00128 virtual bvec demodulate_bits(const Vec<T>& signal) const; 00129 00169 virtual void demodulate_soft_bits(const Vec<T>& rx_symbols, double N0, 00170 vec& soft_bits, 00171 Soft_Method method = LOGMAP) const; 00173 virtual vec demodulate_soft_bits(const Vec<T>& rx_symbols, double N0, 00174 Soft_Method method = LOGMAP) const; 00175 00214 virtual void demodulate_soft_bits(const Vec<T>& rx_symbols, 00215 const Vec<T>& channel, 00216 double N0, vec& soft_bits, 00217 Soft_Method method = LOGMAP) const; 00219 virtual vec demodulate_soft_bits(const Vec<T>& rx_symbols, 00220 const Vec<T>& channel, 00221 double N0, 00222 Soft_Method method = LOGMAP) const; 00223 00224 protected: 00226 bool setup_done; 00228 int k; 00230 int M; 00232 bmat bitmap; 00234 ivec bits2symbols; 00236 Vec<T> symbols; 00239 imat S0; 00242 imat S1; 00243 00245 void calculate_softbit_matrices(); 00246 }; 00247 00248 00249 // ---------------------------------------------------------------------- 00250 // Type definitions of Modulator_1D and Modulator_2D 00251 // ---------------------------------------------------------------------- 00252 00257 typedef Modulator<double> Modulator_1D; 00258 00263 typedef Modulator<std::complex<double> > Modulator_2D; 00264 00265 00266 // ---------------------------------------------------------------------- 00267 // Implementation of templated Modulator members 00268 // ---------------------------------------------------------------------- 00269 00270 template<typename T> 00271 Modulator<T>::Modulator() : 00272 setup_done(false), k(0), M(0), bitmap(""), bits2symbols(""), symbols(""), 00273 S0(""), S1("") {} 00274 00275 template<typename T> 00276 Modulator<T>::Modulator(const Vec<T> &symbols, const ivec &bits2symbols) 00277 { 00278 set(symbols, bits2symbols); 00279 } 00280 00281 template<typename T> 00282 void Modulator<T>::set(const Vec<T> &in_symbols, const ivec &in_bits2symbols) 00283 { 00284 it_assert(in_symbols.size() == in_bits2symbols.size(), 00285 "Modulator<T>::set(): Number of symbols and bits2symbols does not match"); 00286 it_assert(is_even(in_symbols.size()) && (in_symbols.size() > 0), 00287 "Modulator<T>::set(): Number of symbols needs to be even and non-zero"); 00288 it_assert((max(in_bits2symbols) == in_bits2symbols.size() - 1) 00289 && (min(in_bits2symbols) == 0), "Modulator<T>::set(): Improper bits2symbol vector"); 00290 symbols = in_symbols; 00291 bits2symbols = in_bits2symbols; 00292 M = bits2symbols.size(); 00293 k = levels2bits(M); 00294 bitmap.set_size(M, k); 00295 for (int m = 0; m < M; m++) { 00296 bitmap.set_row(bits2symbols(m), dec2bin(k, m)); 00297 } 00298 calculate_softbit_matrices(); 00299 setup_done = true; 00300 } 00301 00302 00303 template<typename T> 00304 void Modulator<T>::modulate(const ivec &symbolnumbers, Vec<T>& output) const 00305 { 00306 it_assert_debug(setup_done, "Modulator<T>::modulate(): Modulator not ready."); 00307 output.set_size(symbolnumbers.length()); 00308 for (int i = 0; i < symbolnumbers.length(); i++) 00309 output(i) = symbols(symbolnumbers(i)); 00310 } 00311 00312 template<typename T> 00313 Vec<T> Modulator<T>::modulate(const ivec &symbolnumbers) const 00314 { 00315 Vec<T> output(symbolnumbers.length()); 00316 modulate(symbolnumbers, output); 00317 return output; 00318 } 00319 00320 00321 template<typename T> 00322 void Modulator<T>::demodulate(const Vec<T> &signal, ivec& output) const 00323 { 00324 it_assert_debug(setup_done, "Modulator<T>::demodulate(): Modulator not ready."); 00325 double dist, mindist; 00326 int closest; 00327 output.set_size(signal.size()); 00328 00329 for (int i = 0; i < signal.size(); i++) { 00330 mindist = std::abs(symbols(0) - signal(i)); 00331 closest = 0; 00332 for (int j = 1; j < M; j++) { 00333 dist = std::abs(symbols(j) - signal(i)); 00334 if (dist < mindist) { 00335 mindist = dist; 00336 closest = j; 00337 } 00338 } 00339 output(i) = closest; 00340 } 00341 } 00342 00343 template<typename T> 00344 ivec Modulator<T>::demodulate(const Vec<T>& signal) const 00345 { 00346 ivec output(signal.length()); 00347 demodulate(signal, output); 00348 return output; 00349 } 00350 00351 00352 template<typename T> 00353 void Modulator<T>::modulate_bits(const bvec &bits, Vec<T> &output) const 00354 { 00355 it_assert_debug(setup_done, "Modulator<T>::modulate_bits(): Modulator not ready."); 00356 // Check if some bits have to be cut and print warning message in such 00357 // case. 00358 if (bits.length() % k) { 00359 it_warning("Modulator<T>::modulate_bits(): The number of input bits is not a multiple of k (number of bits per symbol). Remainder bits are not modulated."); 00360 } 00361 int no_symbols = bits.length() / k; 00362 output.set_size(no_symbols); 00363 for (int i = 0; i < no_symbols; i++) { 00364 output(i) = symbols(bits2symbols(bin2dec(bits.mid(i * k, k)))); 00365 } 00366 } 00367 00368 template<typename T> 00369 Vec<T> Modulator<T>::modulate_bits(const bvec &bits) const 00370 { 00371 Vec<T> output; 00372 modulate_bits(bits, output); 00373 return output; 00374 } 00375 00376 template<typename T> 00377 void Modulator<T>::demodulate_bits(const Vec<T> &signal, bvec &bits) const 00378 { 00379 it_assert_debug(setup_done, "Modulator<T>::demodulate_bist(): Modulator not ready."); 00380 double dist, mindist; 00381 int closest; 00382 bits.set_size(k*signal.size()); 00383 00384 for (int i = 0; i < signal.size(); i++) { 00385 mindist = std::abs(symbols(0) - signal(i)); 00386 closest = 0; 00387 for (int j = 1; j < M; j++) { 00388 dist = std::abs(symbols(j) - signal(i)); 00389 if (dist < mindist) { 00390 mindist = dist; 00391 closest = j; 00392 } 00393 } 00394 bits.replace_mid(i*k, bitmap.get_row(closest)); 00395 } 00396 } 00397 00398 template<typename T> 00399 bvec Modulator<T>::demodulate_bits(const Vec<T> &signal) const 00400 { 00401 bvec bits; 00402 demodulate_bits(signal, bits); 00403 return bits; 00404 } 00405 00406 00407 template<typename T> 00408 void Modulator<T>::demodulate_soft_bits(const Vec<T> &rx_symbols, double N0, 00409 vec &soft_bits, 00410 Soft_Method method) const 00411 { 00412 it_assert_debug(setup_done, "Modulator<T>::demodulate_soft_bits(): Modulator not ready."); 00413 double P0, P1, d0min, d1min, temp; 00414 vec metric(M); 00415 00416 soft_bits.set_size(k * rx_symbols.size()); 00417 00418 if (method == LOGMAP) { 00419 for (int l = 0; l < rx_symbols.size(); l++) { 00420 for (int j = 0; j < M; j++) { 00421 metric(j) = std::exp(-sqr(rx_symbols(l) - symbols(j)) / N0); 00422 } 00423 for (int i = 0; i < k; i++) { 00424 P0 = P1 = 0; 00425 for (int j = 0; j < (M >> 1); j++) { 00426 P0 += metric(S0(i, j)); 00427 P1 += metric(S1(i, j)); 00428 } 00429 soft_bits(l*k + i) = trunc_log(P0) - trunc_log(P1); 00430 } 00431 } 00432 } 00433 else { // method == APPROX 00434 for (int l = 0; l < rx_symbols.size(); l++) { 00435 for (int j = 0; j < M; j++) { 00436 metric(j) = sqr(rx_symbols(l) - symbols(j)); 00437 } 00438 for (int i = 0; i < k; i++) { 00439 d0min = d1min = std::numeric_limits<double>::max(); 00440 for (int j = 0; j < (M >> 1); j++) { 00441 temp = metric(S0(i, j)); 00442 if (temp < d0min) { d0min = temp; } 00443 temp = metric(S1(i, j)); 00444 if (temp < d1min) { d1min = temp; } 00445 } 00446 soft_bits(l*k + i) = (-d0min + d1min) / N0; 00447 } 00448 } 00449 } 00450 } 00451 00452 template<typename T> 00453 vec Modulator<T>::demodulate_soft_bits(const Vec<T> &rx_symbols, 00454 double N0, 00455 Soft_Method method) const 00456 { 00457 vec output; 00458 demodulate_soft_bits(rx_symbols, N0, output, method); 00459 return output; 00460 } 00461 00462 template<typename T> 00463 void Modulator<T>::demodulate_soft_bits(const Vec<T> &rx_symbols, 00464 const Vec<T> &channel, double N0, 00465 vec &soft_bits, 00466 Soft_Method method) const 00467 { 00468 it_assert_debug(setup_done, "Modulator_2D::demodulate_soft_bits(): Modulator not ready."); 00469 double P0, P1, d0min, d1min, temp; 00470 vec metric(M); 00471 00472 soft_bits.set_size(k * rx_symbols.size()); 00473 00474 if (method == LOGMAP) { 00475 for (int l = 0; l < rx_symbols.size(); l++) { 00476 for (int j = 0; j < M; j++) { 00477 metric(j) = std::exp(-sqr(rx_symbols(l) - channel(l) * symbols(j)) 00478 / N0); 00479 } 00480 for (int i = 0; i < k; i++) { 00481 P0 = P1 = 0; 00482 for (int j = 0; j < (M >> 1); j++) { 00483 P0 += metric(S0(i, j)); 00484 P1 += metric(S1(i, j)); 00485 } 00486 soft_bits(l*k + i) = trunc_log(P0) - trunc_log(P1); 00487 } 00488 } 00489 } 00490 else { // method == APPROX 00491 for (int l = 0; l < rx_symbols.size(); l++) { 00492 for (int j = 0; j < M; j++) { 00493 metric(j) = sqr(rx_symbols(l) - channel(l) * symbols(j)); 00494 } 00495 for (int i = 0; i < k; i++) { 00496 d0min = d1min = std::numeric_limits<double>::max(); 00497 for (int j = 0; j < (M >> 1); j++) { 00498 temp = metric(S0(i, j)); 00499 if (temp < d0min) { d0min = temp; } 00500 temp = metric(S1(i, j)); 00501 if (temp < d1min) { d1min = temp; } 00502 } 00503 soft_bits(l*k + i) = (-d0min + d1min) / N0; 00504 } 00505 } 00506 } 00507 } 00508 00509 template<typename T> 00510 vec Modulator<T>::demodulate_soft_bits(const Vec<T> &rx_symbols, 00511 const Vec<T> &channel, 00512 double N0, 00513 Soft_Method method) const 00514 { 00515 vec output; 00516 demodulate_soft_bits(rx_symbols, channel, N0, output, method); 00517 return output; 00518 } 00519 00520 template<typename T> 00521 void Modulator<T>::calculate_softbit_matrices() 00522 { 00523 int count0, count1; 00524 00525 // Allocate storage space for the result matrices: 00526 S0.set_size(k, M >> 1, false); 00527 S1.set_size(k, M >> 1, false); 00528 00529 for (int i = 0; i < k; i++) { 00530 count0 = 0; 00531 count1 = 0; 00532 for (int j = 0; j < M; j++) { 00533 if (bitmap(j, i) == bin(0)) { 00534 S0(i, count0++) = j; 00535 } 00536 else { 00537 S1(i, count1++) = j; 00538 } 00539 } 00540 } 00541 } 00542 00543 00544 00545 // ---------------------------------------------------------------------- 00546 // QAM : Modulator_2D 00547 // ---------------------------------------------------------------------- 00548 00569 class QAM : public Modulator<std::complex<double> > 00570 { 00571 public: 00573 QAM() {} 00575 QAM(int M) { set_M(M); } 00577 virtual ~QAM() { } 00579 void set_M(int M); 00580 00582 void demodulate_bits(const cvec& signal, bvec& bits) const; 00584 bvec demodulate_bits(const cvec& signal) const; 00585 00586 protected: 00588 int L; 00590 double scaling_factor; 00591 }; 00592 00593 00594 // ---------------------------------------------------------------------- 00595 // PSK : Modulator<std::complex<double> > 00596 // ---------------------------------------------------------------------- 00597 00618 class PSK : public Modulator<std::complex<double> > 00619 { 00620 public: 00622 PSK() {} 00624 PSK(int M) { set_M(M); } 00626 virtual ~PSK() { } 00628 void set_M(int M); 00629 00631 void demodulate_bits(const cvec& signal, bvec& bits) const; 00633 bvec demodulate_bits(const cvec& signal) const; 00634 }; 00635 00636 00637 // ---------------------------------------------------------------------- 00638 // QPSK : PSK : Modulator<std::complex<double> > 00639 // ---------------------------------------------------------------------- 00640 00660 class QPSK : public PSK 00661 { 00662 public: 00664 QPSK(): PSK(4) {} 00666 virtual ~QPSK() {} 00667 00689 virtual void demodulate_soft_bits(const cvec& rx_symbols, double N0, 00690 vec& soft_bits, 00691 Soft_Method method = LOGMAP) const; 00693 vec demodulate_soft_bits(const cvec& rx_symbols, double N0, 00694 Soft_Method method = LOGMAP) const; 00695 00696 00719 virtual void demodulate_soft_bits(const cvec& rx_symbols, 00720 const cvec& channel, double N0, 00721 vec& soft_bits, 00722 Soft_Method method = LOGMAP) const; 00724 vec demodulate_soft_bits(const cvec& rx_symbols, const cvec& channel, 00725 double N0, Soft_Method method = LOGMAP) const; 00726 }; 00727 00728 00729 // ---------------------------------------------------------------------- 00730 // BPSK_c : PSK : Modulator<std::complex<double> > 00731 // ---------------------------------------------------------------------- 00732 00758 class BPSK_c : public PSK 00759 { 00760 public: 00762 BPSK_c(): PSK(2) {} 00764 virtual ~BPSK_c() {} 00765 00767 void modulate_bits(const bvec& bits, cvec& output) const; 00769 cvec modulate_bits(const bvec& bits) const; 00771 void demodulate_bits(const cvec& signal, bvec& output) const; 00773 bvec demodulate_bits(const cvec& signal) const; 00774 00794 virtual void demodulate_soft_bits(const cvec& rx_symbols, double N0, 00795 vec& soft_bits, 00796 Soft_Method method = LOGMAP) const; 00798 vec demodulate_soft_bits(const cvec& rx_symbols, double N0, 00799 Soft_Method method = LOGMAP) const; 00800 00821 virtual void demodulate_soft_bits(const cvec& rx_symbols, 00822 const cvec& channel, double N0, 00823 vec& soft_bits, 00824 Soft_Method method = LOGMAP) const; 00826 vec demodulate_soft_bits(const cvec& rx_symbols, const cvec& channel, 00827 double N0, Soft_Method method = LOGMAP) const; 00828 }; 00829 00830 00831 00832 // ---------------------------------------------------------------------- 00833 // BPSK : Modulator<double> 00834 // ---------------------------------------------------------------------- 00835 00859 class BPSK : public Modulator<double> 00860 { 00861 public: 00863 BPSK(): Modulator<double>("1.0 -1.0", "0 1") {} 00865 virtual ~BPSK() {} 00866 00868 void modulate_bits(const bvec& bits, vec& output) const; 00870 vec modulate_bits(const bvec& bits) const; 00872 void demodulate_bits(const vec& signal, bvec& output) const; 00874 bvec demodulate_bits(const vec& signal) const; 00875 00893 virtual void demodulate_soft_bits(const vec& rx_symbols, double N0, 00894 vec& soft_bits, 00895 Soft_Method method = LOGMAP) const; 00897 vec demodulate_soft_bits(const vec& rx_symbols, double N0, 00898 Soft_Method method = LOGMAP) const; 00899 00919 virtual void demodulate_soft_bits(const vec& rx_symbols, 00920 const vec& channel, double N0, 00921 vec& soft_bits, 00922 Soft_Method method = LOGMAP) const; 00924 vec demodulate_soft_bits(const vec& rx_symbols, const vec& channel, 00925 double N0, Soft_Method method = LOGMAP) const; 00926 }; 00927 00928 00929 // ---------------------------------------------------------------------- 00930 // PAM_c : Modulator<std::complex<double> > 00931 // ---------------------------------------------------------------------- 00932 00951 class PAM_c : public Modulator<std::complex<double> > 00952 { 00953 public: 00955 PAM_c() {} 00957 PAM_c(int M) { set_M(M); } 00959 virtual ~PAM_c() {} 00961 void set_M(int M); 00962 00964 void demodulate_bits(const cvec& signal, bvec& output) const; 00966 bvec demodulate_bits(const cvec& signal) const; 00967 01007 virtual void demodulate_soft_bits(const cvec& rx_symbols, double N0, 01008 vec& soft_bits, 01009 Soft_Method method = LOGMAP) const; 01011 virtual vec demodulate_soft_bits(const cvec& rx_symbols, double N0, 01012 Soft_Method method = LOGMAP) const; 01013 01052 virtual void demodulate_soft_bits(const cvec& rx_symbols, 01053 const cvec& channel, double N0, 01054 vec& soft_bits, 01055 Soft_Method method = LOGMAP) const; 01057 virtual vec demodulate_soft_bits(const cvec& rx_symbols, 01058 const cvec& channel, double N0, 01059 Soft_Method method = LOGMAP) const; 01060 01061 protected: 01063 double scaling_factor; 01064 }; 01065 01066 01067 // ---------------------------------------------------------------------- 01068 // PAM : Modulator<double> 01069 // ---------------------------------------------------------------------- 01070 01087 class PAM : public Modulator<double> 01088 { 01089 public: 01091 PAM() {} 01093 PAM(int M) { set_M(M); } 01095 virtual ~PAM() {} 01097 void set_M(int M); 01098 01100 void demodulate_bits(const vec& signal, bvec& output) const; 01102 bvec demodulate_bits(const vec& signal) const; 01103 01104 protected: 01106 double scaling_factor; 01107 }; 01108 01109 } // namespace itpp 01110 01111 #endif // #ifndef MODULATOR_H
Generated on Wed Jul 27 2011 16:27:05 for IT++ by Doxygen 1.7.4