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

Generated on Thu Apr 23 20:06:47 2009 for IT++ by Doxygen 1.5.8