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