00001
00029 #ifndef MODULATOR_ND_H
00030 #define MODULATOR_ND_H
00031
00032 #include <itpp/base/vec.h>
00033 #include <itpp/base/array.h>
00034 #include <itpp/comm/llr.h>
00035
00036 namespace itpp
00037 {
00038
00043
00044
00045
00046
00058 class Modulator_ND
00059 {
00060 public:
00062 enum Soft_Demod_Method {
00064 FULL_ENUM_LOGMAP,
00066 ZF_LOGMAP
00067 };
00068
00070 Modulator_ND(LLR_calc_unit llrcalc_in = LLR_calc_unit()):
00071 llrcalc(llrcalc_in) {}
00073 ~Modulator_ND() {}
00074
00076 void set_llrcalc(LLR_calc_unit llrcalc_in) { llrcalc = llrcalc_in; };
00077
00079 LLR_calc_unit get_llrcalc() const { return llrcalc; }
00080
00082 int get_dim() const { return nt; }
00083
00085 ivec get_k() const { return k; }
00086
00088 ivec get_M() const { return M; }
00089
00090 protected:
00092 int nt;
00094 LLR_calc_unit llrcalc;
00096 ivec k;
00098 ivec M;
00100 Array<bmat> bitmap;
00102 Array<ivec> bits2symbols;
00103
00105 QLLRvec probabilities(QLLR l);
00106
00108 Array<QLLRvec> probabilities(const QLLRvec &l);
00109
00128 void update_LLR(const Array<QLLRvec> &logP_apriori, const ivec &s,
00129 QLLR scaled_norm, QLLRvec &num, QLLRvec &denom);
00130
00150 void update_LLR(const Array<QLLRvec> &logP_apriori, int s,
00151 QLLR scaled_norm, int j, QLLRvec &num, QLLRvec &denom);
00152 };
00153
00154
00155
00156
00157
00158
00183 class Modulator_NRD : public Modulator_ND
00184 {
00185 public:
00187 Modulator_NRD() {}
00189 ~Modulator_NRD() {}
00190
00192 Array<vec> get_symbols() const { return symbols; }
00193
00195 void modulate_bits(const bvec &bits, vec &symbols) const;
00196
00198 vec modulate_bits(const bvec &bits) const;
00199
00218 void demodulate_soft_bits(const vec &y, const mat &H, double sigma2,
00219 const QLLRvec &LLR_apriori,
00220 QLLRvec &LLR_aposteriori,
00221 Soft_Demod_Method method);
00222
00241 QLLRvec demodulate_soft_bits(const vec &y, const mat &H, double sigma2,
00242 const QLLRvec &LLR_apriori,
00243 Soft_Demod_Method method);
00244
00273 void demodulate_soft_bits(const vec &y, const mat &H, double sigma2,
00274 const QLLRvec &LLR_apriori,
00275 QLLRvec &LLR_aposteriori);
00276
00284 void demodulate_soft_bits(const vec &y, const vec &h, double sigma2,
00285 const QLLRvec &LLR_apriori,
00286 QLLRvec &LLR_aposteriori);
00287
00288
00290 friend std::ostream &operator<<(std::ostream &os, const Modulator_NRD &m);
00291
00292 protected:
00294 Array<vec> symbols;
00295
00310 void update_norm(double &norm, int k, int sold, int snew, const vec &ytH,
00311 const mat &HtH, const ivec &s);
00312 };
00313
00318 std::ostream &operator<<(std::ostream &os, const Modulator_NRD &m);
00319
00320
00321
00322
00323
00324
00335 class Modulator_NCD : public Modulator_ND
00336 {
00337 public:
00339 Modulator_NCD() {}
00341 ~Modulator_NCD() {}
00342
00344 Array<cvec> get_symbols() const { return symbols; }
00345
00347 void modulate_bits(const bvec &bits, cvec &symbols) const;
00348
00350 cvec modulate_bits(const bvec &bits) const;
00351
00353
00372 void demodulate_soft_bits(const cvec &y, const cmat &H, double sigma2,
00373 const QLLRvec &LLR_apriori,
00374 QLLRvec &LLR_aposteriori,
00375 Soft_Demod_Method method);
00376
00396 QLLRvec demodulate_soft_bits(const cvec &y, const cmat &H, double sigma2,
00397 const QLLRvec &LLR_apriori,
00398 Soft_Demod_Method method);
00399
00428 void demodulate_soft_bits(const cvec &y, const cmat &H, double sigma2,
00429 const QLLRvec &LLR_apriori,
00430 QLLRvec &LLR_aposteriori);
00431
00439 void demodulate_soft_bits(const cvec &y, const cvec &H, double sigma2,
00440 const QLLRvec &LLR_apriori,
00441 QLLRvec &LLR_aposteriori);
00442
00444 friend std::ostream &operator<<(std::ostream &os, const Modulator_NCD &m);
00445
00446 protected:
00448 Array<cvec> symbols;
00449
00464 void update_norm(double &norm, int k, int sold, int snew, const cvec &ytH,
00465 const cmat &HtH, const ivec &s);
00466 };
00467
00472 std::ostream &operator<<(std::ostream &os, const Modulator_NCD &m);
00473
00474
00475
00476
00477
00478
00517 class ND_UPAM : public Modulator_NRD
00518 {
00519 public:
00521 ND_UPAM(int nt = 1, int Mary = 2);
00523 ~ND_UPAM() {}
00524
00526 void set_M(int nt = 1, int Mary = 2);
00527
00529 void set_M(int nt = 1, ivec Mary = "2");
00530
00554 int sphere_decoding(const vec &y, const mat &H, double rmin, double rmax,
00555 double stepup, QLLRvec &detected_bits);
00556
00557 private:
00558
00559 int sphere_search_SE(const vec &y, const mat &H, const imat &zrange,
00560 double r, ivec &zhat);
00561
00562 vec spacing;
00563
00564 inline int sign_nozero_i(int a) { return (a > 0 ? 1 : -1); }
00565 inline int sign_nozero_i(double a) { return (a > 0.0 ? 1 : -1); }
00566 };
00567
00568
00569
00570
00571
00576 class ND_UQAM : public Modulator_NCD
00577 {
00578 public:
00580 ND_UQAM(int nt = 1, int Mary = 4);
00582 ~ND_UQAM() {}
00583
00585 void set_M(int nt = 1, int Mary = 4);
00586
00588 void set_M(int nt = 1, ivec Mary = "4");
00589
00590 protected:
00591 ivec L;
00592 };
00593
00594
00595
00596
00597
00602 class ND_UPSK : public Modulator_NCD
00603 {
00604 public:
00606 ND_UPSK(int nt = 1, int Mary = 4);
00608 ~ND_UPSK() {}
00609
00611 void set_M(int nt = 1, int Mary = 4);
00612
00614 void set_M(int nt = 1, ivec Mary = "4");
00615 };
00616
00617
00618 }
00619
00620 #endif // #ifndef MODULATOR_ND_H
00621