00001
00029 #ifndef LLR_H
00030 #define LLR_H
00031
00032 #include <limits>
00033 #include <itpp/base/vec.h>
00034 #include <itpp/base/mat.h>
00035 #include <itpp/base/specmat.h>
00036 #include <itpp/base/matfunc.h>
00037 #include <limits>
00038
00039 namespace itpp
00040 {
00041
00045 typedef signed int QLLR;
00046
00050 typedef Vec<QLLR> QLLRvec;
00051
00055 typedef Mat<QLLR> QLLRmat;
00056
00060 const QLLR QLLR_MAX = (std::numeric_limits<QLLR>::max() >> 4);
00061
00062
00114 class LLR_calc_unit
00115 {
00116 public:
00118 LLR_calc_unit();
00119
00125 LLR_calc_unit(short int Dint1, short int Dint2, short int Dint3);
00126
00155 void init_llr_tables(short int Dint1 = 12, short int Dint2 = 300,
00156 short int Dint3 = 7);
00157
00159 QLLR to_qllr(double l) const;
00160
00162 QLLRvec to_qllr(const vec &l) const;
00163
00165 QLLRmat to_qllr(const mat &l) const;
00166
00168 double to_double(QLLR l) const;
00169
00171 vec to_double(const QLLRvec &l) const;
00172
00174 mat to_double(const QLLRmat &l) const;
00175
00181 inline QLLR jaclog(QLLR a, QLLR b) const;
00182
00183
00184
00193 QLLR Boxplus(QLLR a, QLLR b) const;
00194
00200 inline QLLR logexp(QLLR x) const;
00201
00203 ivec get_Dint();
00204
00206 friend std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &l);
00207
00208 private:
00210 ivec construct_logexp_table();
00211
00213 ivec logexp_table;
00214
00216 short int Dint1, Dint2, Dint3;
00217 };
00218
00223 std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &lcu);
00224
00225
00226
00227
00228
00229
00230 inline double LLR_calc_unit::to_double(QLLR l) const
00231 {
00232 return static_cast<double>(l) / (1 << Dint1);
00233 }
00234
00235 inline QLLR LLR_calc_unit::to_qllr(double l) const
00236 {
00237 double QLLR_MAX_double = to_double(QLLR_MAX);
00238
00239 if (l > QLLR_MAX_double) {
00240 it_info_debug("LLR_calc_unit::to_qllr(): LLR overflow");
00241 return QLLR_MAX;
00242 }
00243 if (l < -QLLR_MAX_double) {
00244 it_info_debug("LLR_calc_unit::to_qllr(): LLR overflow");
00245 return -QLLR_MAX;
00246 }
00247 return static_cast<QLLR>(std::floor(0.5 + (1 << Dint1) * l));
00248 }
00249
00250
00251 inline QLLR LLR_calc_unit::logexp(QLLR x) const
00252 {
00253 it_assert_debug(x >= 0, "LLR_calc_unit::logexp(): Wrong LLR value");
00254 int ind = x >> Dint3;
00255 if (ind >= Dint2)
00256 return 0;
00257
00258 it_assert_debug(ind >= 0, "LLR_calc_unit::logexp(): Internal error");
00259 it_assert_debug(ind < Dint2, "LLR_calc_unit::logexp(): internal error");
00260
00261
00262
00263
00264
00265
00266 return logexp_table(ind);
00267 }
00268
00269
00270 inline QLLR LLR_calc_unit::jaclog(QLLR a, QLLR b) const
00271 {
00272 QLLR x, maxab;
00273
00274 if (a > b) {
00275 maxab = a;
00276 x = a - b;
00277 }
00278 else {
00279 maxab = b;
00280 x = b - a;
00281 }
00282
00283 if (maxab >= QLLR_MAX)
00284 return QLLR_MAX;
00285 else
00286 return (maxab + logexp(x));
00287 }
00288
00289 }
00290
00291 #endif