IT++ Logo

llr.h

Go to the documentation of this file.
00001 
00030 #ifndef LLR_H
00031 #define LLR_H
00032 
00033 #include <limits>
00034 #include <itpp/base/vec.h>
00035 #include <itpp/base/mat.h>
00036 #include <itpp/base/specmat.h>
00037 #include <itpp/base/matfunc.h>
00038 #include <limits>
00039 
00040 namespace itpp
00041 {
00042 
00046 typedef signed int QLLR;
00047 
00051 typedef Vec<QLLR> QLLRvec;
00052 
00056 typedef Mat<QLLR> QLLRmat;
00057 
00061 const QLLR QLLR_MAX = (std::numeric_limits<QLLR>::max() >> 4);
00062 // added some margin to make sure the sum of two LLR is still permissible
00063 
00124 class LLR_calc_unit
00125 {
00126 public:
00128   LLR_calc_unit();
00129 
00135   LLR_calc_unit(short int Dint1, short int Dint2, short int Dint3);
00136 
00165   void init_llr_tables(short int Dint1 = 12, short int Dint2 = 300,
00166                        short int Dint3 = 7);
00167 
00169   QLLR to_qllr(double l) const;
00170 
00172   QLLRvec to_qllr(const vec &l) const;
00173 
00175   QLLRmat to_qllr(const mat &l) const;
00176 
00178   double to_double(QLLR l) const;
00179 
00181   vec to_double(const QLLRvec &l) const;
00182 
00184   mat to_double(const QLLRmat &l) const;
00185 
00191   inline QLLR jaclog(QLLR a, QLLR b) const;
00192   // Note: a version of this function taking "double" values as input
00193   // is deliberately omitted, because this is rather slow.
00194 
00203   QLLR Boxplus(QLLR a, QLLR b) const;
00204 
00210   inline QLLR logexp(QLLR x) const;
00211 
00213   ivec get_Dint();
00214 
00216   friend std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &l);
00217 
00218 private:
00220   ivec construct_logexp_table();
00221 
00223   ivec logexp_table;
00224 
00226   short int Dint1, Dint2, Dint3;
00227 };
00228 
00233 std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &lcu);
00234 
00235 
00236 // ----------------------------------------------------------------------
00237 // implementation of some inline functions
00238 // ----------------------------------------------------------------------
00239 
00240 inline double LLR_calc_unit::to_double(QLLR l) const
00241 {
00242   return static_cast<double>(l) / (1 << Dint1);
00243 }
00244 
00245 inline QLLR LLR_calc_unit::to_qllr(double l) const
00246 {
00247   double QLLR_MAX_double = to_double(QLLR_MAX);
00248   // Don't abort when overflow occurs, just saturate the QLLR
00249   if (l > QLLR_MAX_double) {
00250     it_info_debug("LLR_calc_unit::to_qllr(): LLR overflow");
00251     return QLLR_MAX;
00252   }
00253   if (l < -QLLR_MAX_double) {
00254     it_info_debug("LLR_calc_unit::to_qllr(): LLR overflow");
00255     return -QLLR_MAX;
00256   }
00257   return static_cast<QLLR>(std::floor(0.5 + (1 << Dint1) * l));
00258 }
00259 
00260 
00261 inline QLLR LLR_calc_unit::logexp(QLLR x) const
00262 {
00263   it_assert_debug(x >= 0, "LLR_calc_unit::logexp(): Wrong LLR value");
00264   int ind = x >> Dint3;
00265   if (ind >= Dint2) // outside table
00266     return 0;
00267 
00268   it_assert_debug(ind >= 0, "LLR_calc_unit::logexp(): Internal error");
00269   it_assert_debug(ind < Dint2, "LLR_calc_unit::logexp(): internal error");
00270 
00271   // With interpolation
00272   // int delta=x-(ind<<Dint3);
00273   // return ((delta*logexp_table(ind+1) + ((1<<Dint3)-delta)*logexp_table(ind)) >> Dint3);
00274 
00275   // Without interpolation
00276   return logexp_table(ind);
00277 }
00278 
00279 
00280 inline QLLR LLR_calc_unit::jaclog(QLLR a, QLLR b) const
00281 {
00282   QLLR x, maxab;
00283 
00284   if (a > b) {
00285     maxab = a;
00286     x = a - b;
00287   }
00288   else {
00289     maxab = b;
00290     x = b - a;
00291   }
00292 
00293   if (maxab >= QLLR_MAX)
00294     return QLLR_MAX;
00295   else
00296     return (maxab + logexp(x));
00297 }
00298 
00299 }
00300 
00301 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Wed Jan 20 23:03:05 2010 for IT++ by Doxygen 1.6.2