00001 00030 #ifndef MODULATOR_ND_H 00031 #define MODULATOR_ND_H 00032 00033 #include <itpp/base/vec.h> 00034 #include <itpp/base/array.h> 00035 #include <itpp/comm/llr.h> 00036 00037 namespace itpp { 00038 00043 // ---------------------------------------------------------------------- 00044 // Modulator_ND 00045 // ---------------------------------------------------------------------- 00046 00058 class Modulator_ND { 00059 public: 00061 enum Soft_Demod_Method { 00063 FULL_ENUM_LOGMAP, 00065 ZF_LOGMAP 00066 }; 00067 00069 Modulator_ND(LLR_calc_unit llrcalc_in = LLR_calc_unit()): 00070 llrcalc(llrcalc_in) {} 00072 ~Modulator_ND() {} 00073 00075 void set_llrcalc(LLR_calc_unit llrcalc_in) { llrcalc = llrcalc_in; }; 00076 00078 LLR_calc_unit get_llrcalc() const { return llrcalc; } 00079 00081 int get_dim() const { return nt; } 00082 00084 ivec get_k() const { return k; } 00085 00087 ivec get_M() const { return M; } 00088 00089 protected: 00091 int nt; 00093 LLR_calc_unit llrcalc; 00095 ivec k; 00097 ivec M; 00099 Array<bmat> bitmap; 00101 Array<ivec> bits2symbols; 00102 00104 QLLRvec probabilities(QLLR l); // some abuse of what QLLR stands for... 00105 00107 Array<QLLRvec> probabilities(const QLLRvec &l); 00108 00127 void update_LLR(const Array<QLLRvec> &logP_apriori, const ivec &s, 00128 QLLR scaled_norm, QLLRvec &num, QLLRvec &denom); 00129 00149 void update_LLR(const Array<QLLRvec> &logP_apriori, int s, 00150 QLLR scaled_norm, int j, QLLRvec &num, QLLRvec &denom); 00151 }; 00152 00153 00154 // ---------------------------------------------------------------------- 00155 // Modulator_NRD 00156 // ---------------------------------------------------------------------- 00157 00182 class Modulator_NRD : public Modulator_ND { 00183 public: 00185 Modulator_NRD() {} 00187 ~Modulator_NRD() {} 00188 00190 Array<vec> get_symbols() const { return symbols; } 00191 00193 void modulate_bits(const bvec &bits, vec &symbols) const; 00194 00196 vec modulate_bits(const bvec &bits) const; 00197 00216 void demodulate_soft_bits(const vec &y, const mat &H, double sigma2, 00217 const QLLRvec &LLR_apriori, 00218 QLLRvec &LLR_aposteriori, 00219 Soft_Demod_Method method); 00220 00239 QLLRvec demodulate_soft_bits(const vec &y, const mat &H, double sigma2, 00240 const QLLRvec &LLR_apriori, 00241 Soft_Demod_Method method); 00242 00271 void demodulate_soft_bits(const vec &y, const mat &H, double sigma2, 00272 const QLLRvec &LLR_apriori, 00273 QLLRvec &LLR_aposteriori); 00274 00282 void demodulate_soft_bits(const vec &y, const vec &h, double sigma2, 00283 const QLLRvec &LLR_apriori, 00284 QLLRvec &LLR_aposteriori); 00285 00286 00288 friend std::ostream &operator<<(std::ostream &os, const Modulator_NRD &m); 00289 00290 protected: 00292 Array<vec> symbols; 00293 00308 void update_norm(double &norm, int k, int sold, int snew, const vec &ytH, 00309 const mat &HtH, const ivec &s); 00310 }; 00311 00316 std::ostream &operator<<(std::ostream &os, const Modulator_NRD &m); 00317 00318 00319 // ---------------------------------------------------------------------- 00320 // Modulator_NCD 00321 // ---------------------------------------------------------------------- 00322 00333 class Modulator_NCD : public Modulator_ND { 00334 public: 00336 Modulator_NCD() {} 00338 ~Modulator_NCD() {} 00339 00341 Array<cvec> get_symbols() const { return symbols; } 00342 00344 void modulate_bits(const bvec &bits, cvec &symbols) const; 00345 00347 cvec modulate_bits(const bvec &bits) const; 00348 00350 00369 void demodulate_soft_bits(const cvec &y, const cmat &H, double sigma2, 00370 const QLLRvec &LLR_apriori, 00371 QLLRvec &LLR_aposteriori, 00372 Soft_Demod_Method method); 00373 00393 QLLRvec demodulate_soft_bits(const cvec &y, const cmat &H, double sigma2, 00394 const QLLRvec &LLR_apriori, 00395 Soft_Demod_Method method); 00396 00425 void demodulate_soft_bits(const cvec &y, const cmat &H, double sigma2, 00426 const QLLRvec &LLR_apriori, 00427 QLLRvec &LLR_aposteriori); 00428 00436 void demodulate_soft_bits(const cvec &y, const cvec &H, double sigma2, 00437 const QLLRvec &LLR_apriori, 00438 QLLRvec &LLR_aposteriori); 00439 00441 friend std::ostream &operator<<(std::ostream &os, const Modulator_NCD &m); 00442 00443 protected: 00445 Array<cvec> symbols; 00446 00461 void update_norm(double &norm, int k, int sold, int snew, const cvec &ytH, 00462 const cmat &HtH, const ivec &s); 00463 }; 00464 00469 std::ostream &operator<<(std::ostream &os, const Modulator_NCD &m); 00470 00471 00472 // ---------------------------------------------------------------------- 00473 // ND_UPAM 00474 // ---------------------------------------------------------------------- 00475 00514 class ND_UPAM : public Modulator_NRD { 00515 public: 00517 ND_UPAM(int nt = 1, int Mary = 2); 00519 ~ND_UPAM() {} 00520 00522 void set_M(int nt = 1, int Mary = 2); 00523 00525 void set_M(int nt = 1, ivec Mary = "2"); 00526 00550 int sphere_decoding(const vec &y, const mat &H, double rmin, double rmax, 00551 double stepup, QLLRvec &detected_bits); 00552 00553 private: 00554 // Sphere decoding search with Schnorr Eucner strategy. 00555 int sphere_search_SE(const vec &y, const mat &H, const imat &zrange, 00556 double r, ivec &zhat); 00557 00558 vec spacing; // spacing between the constellation points 00559 00560 inline int sign_nozero_i(int a) { return (a > 0 ? 1 : -1); } 00561 inline int sign_nozero_i(double a) { return (a > 0.0 ? 1 : -1); } 00562 }; 00563 00564 // ---------------------------------------------------------------------- 00565 // ND_UQAM 00566 // ---------------------------------------------------------------------- 00567 00572 class ND_UQAM : public Modulator_NCD { 00573 public: 00575 ND_UQAM(int nt = 1, int Mary = 4); 00577 ~ND_UQAM() {} 00578 00580 void set_M(int nt = 1, int Mary = 4); 00581 00583 void set_M(int nt = 1, ivec Mary = "4"); 00584 00585 protected: 00586 ivec L; 00587 }; 00588 00589 // ---------------------------------------------------------------------- 00590 // ND_UPSK 00591 // ---------------------------------------------------------------------- 00592 00597 class ND_UPSK : public Modulator_NCD { 00598 public: 00600 ND_UPSK(int nt = 1, int Mary = 4); 00602 ~ND_UPSK() {} 00603 00605 void set_M(int nt = 1, int Mary = 4); 00606 00608 void set_M(int nt = 1, ivec Mary = "4"); 00609 }; 00610 00611 00612 } // namespace itpp 00613 00614 #endif // #ifndef MODULATOR_ND_H 00615
Generated on Sun Dec 9 17:31:02 2007 for IT++ by Doxygen 1.5.4