IT++ Logo
llr.h
Go to the documentation of this file.
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 // added some margin to make sure the sum of two LLR is still permissible
00062 
00123 class LLR_calc_unit
00124 {
00125 public:
00127   LLR_calc_unit();
00128 
00134   LLR_calc_unit(short int Dint1, short int Dint2, short int Dint3);
00135 
00164   void init_llr_tables(short int Dint1 = 12, short int Dint2 = 300,
00165                        short int Dint3 = 7);
00166 
00168   QLLR to_qllr(double l) const;
00169 
00171   QLLRvec to_qllr(const vec &l) const;
00172 
00174   QLLRmat to_qllr(const mat &l) const;
00175 
00177   double to_double(QLLR l) const;
00178 
00180   vec to_double(const QLLRvec &l) const;
00181 
00183   mat to_double(const QLLRmat &l) const;
00184 
00190   inline QLLR jaclog(QLLR a, QLLR b) const;
00191   // Note: a version of this function taking "double" values as input
00192   // is deliberately omitted, because this is rather slow.
00193 
00202   QLLR Boxplus(QLLR a, QLLR b) const;
00203 
00209   inline QLLR logexp(QLLR x) const;
00210 
00212   ivec get_Dint();
00213 
00215   friend std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &l);
00216 
00217 private:
00219   ivec construct_logexp_table();
00220 
00222   ivec logexp_table;
00223 
00225   short int Dint1, Dint2, Dint3;
00226 };
00227 
00232 std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &lcu);
00233 
00234 
00235 // ----------------------------------------------------------------------
00236 // implementation of some inline functions
00237 // ----------------------------------------------------------------------
00238 
00239 inline double LLR_calc_unit::to_double(QLLR l) const
00240 {
00241   return static_cast<double>(l) / (1 << Dint1);
00242 }
00243 
00244 inline QLLR LLR_calc_unit::to_qllr(double l) const
00245 {
00246   double QLLR_MAX_double = to_double(QLLR_MAX);
00247   // Don't abort when overflow occurs, just saturate the QLLR
00248   if (l > QLLR_MAX_double) {
00249     it_info_debug("LLR_calc_unit::to_qllr(): LLR overflow");
00250     return QLLR_MAX;
00251   }
00252   if (l < -QLLR_MAX_double) {
00253     it_info_debug("LLR_calc_unit::to_qllr(): LLR overflow");
00254     return -QLLR_MAX;
00255   }
00256   return static_cast<QLLR>(std::floor(0.5 + (1 << Dint1) * l));
00257 }
00258 
00259 
00260 inline QLLR LLR_calc_unit::logexp(QLLR x) const
00261 {
00262   it_assert_debug(x >= 0, "LLR_calc_unit::logexp(): Wrong LLR value");
00263   int ind = x >> Dint3;
00264   if (ind >= Dint2) // outside table
00265     return 0;
00266 
00267   it_assert_debug(ind >= 0, "LLR_calc_unit::logexp(): Internal error");
00268   it_assert_debug(ind < Dint2, "LLR_calc_unit::logexp(): internal error");
00269 
00270   // With interpolation
00271   // int delta=x-(ind<<Dint3);
00272   // return ((delta*logexp_table(ind+1) + ((1<<Dint3)-delta)*logexp_table(ind)) >> Dint3);
00273 
00274   // Without interpolation
00275   return logexp_table(ind);
00276 }
00277 
00278 
00279 inline QLLR LLR_calc_unit::jaclog(QLLR a, QLLR b) const
00280 {
00281   QLLR x, maxab;
00282 
00283   if (a > b) {
00284     maxab = a;
00285     x = a - b;
00286   }
00287   else {
00288     maxab = b;
00289     x = b - a;
00290   }
00291 
00292   if (maxab >= QLLR_MAX)
00293     return QLLR_MAX;
00294   else
00295     return (maxab + logexp(x));
00296 }
00297 
00298 }
00299 
00300 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Sat Jul 9 2011 15:21:31 for IT++ by Doxygen 1.7.4