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 
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 
00114   class LLR_calc_unit {
00115   public:
00117     LLR_calc_unit();
00118 
00124     LLR_calc_unit(short int Dint1, short int Dint2, short int Dint3);
00125 
00154     void init_llr_tables(short int Dint1 = 12, short int Dint2 = 300,
00155                          short int Dint3 = 7);
00156 
00158     QLLR to_qllr(double l) const;
00159 
00161     QLLRvec to_qllr(const vec &l) const;
00162 
00164     QLLRmat to_qllr(const mat &l) const;
00165 
00167     double to_double(QLLR l) const;
00168 
00170     vec to_double(const QLLRvec &l) const;
00171 
00173     mat to_double(const QLLRmat &l) const;
00174 
00180     inline QLLR jaclog(QLLR a, QLLR b) const;
00181     // Note: a version of this function taking "double" values as input
00182     // is deliberately omitted, because this is rather slow.
00183 
00192     QLLR Boxplus(QLLR a, QLLR b) const;
00193 
00199     inline QLLR logexp(QLLR x) const;
00200 
00202     ivec get_Dint();
00203 
00205     friend std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &l);
00206 
00207   private:
00209     ivec construct_logexp_table();
00210 
00212     ivec logexp_table;
00213 
00215     short int Dint1, Dint2, Dint3;
00216   };
00217 
00222   std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &lcu);
00223 
00224 
00225   // ----------------------------------------------------------------------
00226   // implementation of some inline functions
00227   // ----------------------------------------------------------------------
00228 
00229   inline double LLR_calc_unit::to_double(QLLR l) const
00230   {
00231     return static_cast<double>(l) / (1<<Dint1);
00232   }
00233 
00234   inline QLLR LLR_calc_unit::to_qllr(double l) const
00235   {
00236     double QLLR_MAX_double = to_double(QLLR_MAX);
00237     // Don't abort when overflow occurs, just saturate the QLLR
00238     if (l > QLLR_MAX_double) {
00239       it_info_debug("LLR_calc_unit::to_qllr(): LLR overflow");
00240       return QLLR_MAX;
00241     }
00242     if (l < -QLLR_MAX_double) {
00243       it_info_debug("LLR_calc_unit::to_qllr(): LLR overflow");
00244       return -QLLR_MAX;
00245     }
00246     return static_cast<QLLR>(std::floor(0.5 + (1<<Dint1) * l));
00247   }
00248 
00249 
00250   inline QLLR LLR_calc_unit::logexp(QLLR x) const
00251   {
00252     it_assert_debug(x >= 0,"LLR_calc_unit::logexp(): Wrong LLR value");
00253     int ind = x >> Dint3;
00254     if (ind >= Dint2) // outside table
00255       return 0;
00256 
00257     it_assert_debug(ind >= 0,"LLR_calc_unit::logexp(): Internal error");
00258     it_assert_debug(ind < Dint2,"LLR_calc_unit::logexp(): internal error");
00259 
00260     // With interpolation
00261     // int delta=x-(ind<<Dint3);
00262     // return ((delta*logexp_table(ind+1) + ((1<<Dint3)-delta)*logexp_table(ind)) >> Dint3);
00263 
00264     // Without interpolation
00265     return logexp_table(ind);
00266   }
00267 
00268 
00269   inline QLLR LLR_calc_unit::jaclog(QLLR a, QLLR b) const
00270   {
00271     QLLR x, maxab;
00272 
00273     if (a > b) {
00274       maxab = a;
00275       x = a - b;
00276     }
00277     else {
00278       maxab = b;
00279       x = b - a;
00280     }
00281 
00282     if (maxab >= QLLR_MAX)
00283       return QLLR_MAX;
00284     else
00285       return (maxab + logexp(x));
00286   }
00287 
00288 }
00289 
00290 #endif
SourceForge Logo

Generated on Sat Apr 19 10:57:51 2008 for IT++ by Doxygen 1.5.5