IT++ Logo

llr.cpp

Go to the documentation of this file.
00001 
00031 #include <itpp/comm/llr.h>
00032 
00033 
00034 namespace itpp
00035 {
00036 
00037 LLR_calc_unit::LLR_calc_unit()
00038 {
00039   init_llr_tables();
00040 }
00041 
00042 LLR_calc_unit::LLR_calc_unit(short int d1, short int d2, short int d3)
00043 {
00044   init_llr_tables(d1, d2, d3);
00045 }
00046 
00047 ivec LLR_calc_unit::get_Dint()
00048 {
00049   ivec r(3);
00050   r(0) = Dint1;
00051   r(1) = Dint2;
00052   r(2) = Dint3;
00053   return r;
00054 }
00055 
00056 void LLR_calc_unit::init_llr_tables(short int d1, short int d2, short int d3)
00057 {
00058   Dint1 = d1;      // 1<<Dint1 determines how integral LLRs relate to real LLRs (to_double=(1<<Dint)*int_llr)
00059   Dint2 = d2;      // number of entries in table for LLR operations
00060   Dint3 = d3;      // table resolution is 2^(-(Dint1-Dint3))
00061   logexp_table = construct_logexp_table();
00062 }
00063 
00064 ivec LLR_calc_unit::construct_logexp_table()
00065 {
00066   ivec result(Dint2);
00067   for (int i = 0; i < Dint2; i++) {
00068     double x = pow2(static_cast<double>(Dint3 - Dint1)) * i;
00069     result(i) = to_qllr(std::log(1 + std::exp(-x)));
00070   }
00071   it_assert(length(result) == Dint2, "Ldpc_codec::construct_logexp_table()");
00072 
00073   return result;
00074 }
00075 
00076 QLLRvec LLR_calc_unit::to_qllr(const vec &l) const
00077 {
00078   int n = length(l);
00079   ivec result(n);
00080   for (int i = 0; i < n; i++) {
00081     result.set(i, to_qllr(l(i)));
00082   }
00083   return result;
00084 }
00085 
00086 vec LLR_calc_unit::to_double(const QLLRvec &l) const
00087 {
00088   int n = length(l);
00089   vec result(n);
00090   for (int i = 0; i < n; i++) {
00091     result.set(i, to_double(l(i)));
00092   }
00093   return result;
00094 }
00095 
00096 QLLRmat LLR_calc_unit::to_qllr(const mat &l)  const
00097 {
00098   int m = l.rows();
00099   int n = l.cols();
00100   imat result(m, n);
00101   for (int i = 0; i < m; i++) {
00102     for (int j = 0; j < n; j++) {
00103       result.set(i, j, to_qllr(l(i, j)));
00104     }
00105   }
00106   return result;
00107 }
00108 
00109 mat LLR_calc_unit::to_double(const QLLRmat &l) const
00110 {
00111   int m = l.rows();
00112   int n = l.cols();
00113   mat result(m, n);
00114   for (int i = 0; i < m; i++) {
00115     for (int j = 0; j < n; j++) {
00116       result.set(i, j, to_double(l(i, j)));
00117     }
00118   }
00119   return result;
00120 }
00121 
00122 // This function used to be inline, but in my experiments,
00123 // the non-inlined version was actually faster /Martin Senst
00124 QLLR LLR_calc_unit::Boxplus(QLLR a, QLLR b) const
00125 {
00126   QLLR a_abs = (a > 0 ? a : -a);
00127   QLLR b_abs = (b > 0 ? b : -b);
00128   QLLR minabs = (a_abs > b_abs ? b_abs : a_abs);
00129   QLLR term1 = (a > 0 ? (b > 0 ? minabs : -minabs)
00130                     : (b > 0 ? -minabs : minabs));
00131 
00132   if (Dint2 == 0) {  // logmax approximation - avoid looking into empty table
00133     // Don't abort when overflowing, just saturate the QLLR
00134     if (term1 > QLLR_MAX) {
00135       it_info_debug("LLR_calc_unit::Boxplus(): LLR overflow");
00136       return QLLR_MAX;
00137     }
00138     if (term1 < -QLLR_MAX) {
00139       it_info_debug("LLR_calc_unit::Boxplus(): LLR overflow");
00140       return -QLLR_MAX;
00141     }
00142     return term1;
00143   }
00144 
00145   QLLR apb = a + b;
00146   QLLR term2 = logexp((apb > 0 ? apb : -apb));
00147   QLLR amb = a - b;
00148   QLLR term3 = logexp((amb > 0 ? amb : -amb));
00149   QLLR result = term1 + term2 - term3;
00150 
00151   // Don't abort when overflowing, just saturate the QLLR
00152   if (result > QLLR_MAX) {
00153     it_info_debug("LLR_calc_unit::Boxplus() LLR overflow");
00154     return QLLR_MAX;
00155   }
00156   if (result < -QLLR_MAX) {
00157     it_info_debug("LLR_calc_unit::Boxplus() LLR overflow");
00158     return -QLLR_MAX;
00159   }
00160   return result;
00161 }
00162 
00163 std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &lcu)
00164 {
00165   os << "---------- LLR calculation unit -----------------" << std::endl;
00166   os << "LLR_calc_unit table properties:" << std::endl;
00167   os << "The granularity in the LLR representation is "
00168   << pow2(static_cast<double>(-lcu.Dint1)) << std::endl;
00169   os << "The LLR scale factor is " << (1 << lcu.Dint1) << std::endl;
00170   os << "The largest LLR that can be represented is "
00171   << lcu.to_double(QLLR_MAX) << std::endl;
00172   os << "The table resolution is "
00173   << pow2(static_cast<double>(lcu.Dint3 - lcu.Dint1)) << std::endl;
00174   os << "The number of entries in the table is " << lcu.Dint2 << std::endl;
00175   os << "The tables truncates at the LLR value "
00176   << pow2(static_cast<double>(lcu.Dint3 - lcu.Dint1)) * lcu.Dint2
00177   << std::endl;
00178   os << "-------------------------------------------------" << std::endl;
00179   return os;
00180 }
00181 
00182 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Wed Mar 2 2011 22:05:13 for IT++ by Doxygen 1.7.3