00001 00031 #include <itpp/comm/llr.h> 00032 00033 00034 namespace itpp { 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 int n=length(l); 00077 ivec result(n); 00078 for (int i=0; i<n; i++) { 00079 result.set(i,to_qllr(l(i))); 00080 } 00081 return result; 00082 } 00083 00084 vec LLR_calc_unit::to_double(const QLLRvec &l) const { 00085 int n=length(l); 00086 vec result(n); 00087 for (int i=0; i<n; i++) { 00088 result.set(i,to_double(l(i))); 00089 } 00090 return result; 00091 } 00092 00093 QLLRmat LLR_calc_unit::to_qllr(const mat &l) const { 00094 int m=l.rows(); 00095 int n=l.cols(); 00096 imat result(m,n); 00097 for (int i=0; i<m; i++) { 00098 for (int j=0; j<n; j++) { 00099 result.set(i,j,to_qllr(l(i,j))); 00100 } 00101 } 00102 return result; 00103 } 00104 00105 mat LLR_calc_unit::to_double(const QLLRmat &l) const { 00106 int m=l.rows(); 00107 int n=l.cols(); 00108 mat result(m,n); 00109 for (int i=0; i<m; i++) { 00110 for (int j=0; j<n; j++) { 00111 result.set(i,j,to_double(l(i,j))); 00112 } 00113 } 00114 return result; 00115 } 00116 00117 // This function used to be inline, but in my experiments, 00118 // the non-inlined version was actually faster /Martin Senst 00119 QLLR LLR_calc_unit::Boxplus(QLLR a, QLLR b) const 00120 { 00121 QLLR a_abs = (a > 0 ? a : -a); 00122 QLLR b_abs = (b > 0 ? b : -b); 00123 QLLR minabs = (a_abs > b_abs ? b_abs : a_abs); 00124 QLLR term1 = (a > 0 ? (b > 0 ? minabs : -minabs) 00125 : (b > 0 ? -minabs : minabs)); 00126 00127 if (Dint2 == 0) { // logmax approximation - avoid looking into empty table 00128 // Don't abort when overflowing, just saturate the QLLR 00129 if (term1 > QLLR_MAX) { 00130 it_info_debug("LLR_calc_unit::Boxplus(): LLR overflow"); 00131 return QLLR_MAX; 00132 } 00133 if (term1 < -QLLR_MAX) { 00134 it_info_debug("LLR_calc_unit::Boxplus(): LLR overflow"); 00135 return -QLLR_MAX; 00136 } 00137 return term1; 00138 } 00139 00140 QLLR apb = a + b; 00141 QLLR term2 = logexp((apb > 0 ? apb : -apb)); 00142 QLLR amb = a - b; 00143 QLLR term3 = logexp((amb > 0 ? amb : -amb)); 00144 QLLR result = term1 + term2 - term3; 00145 00146 // Don't abort when overflowing, just saturate the QLLR 00147 if (result > QLLR_MAX) { 00148 it_info_debug("LLR_calc_unit::Boxplus() LLR overflow"); 00149 return QLLR_MAX; 00150 } 00151 if (result < -QLLR_MAX) { 00152 it_info_debug("LLR_calc_unit::Boxplus() LLR overflow"); 00153 return -QLLR_MAX; 00154 } 00155 return result; 00156 } 00157 00158 std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &lcu) 00159 { 00160 os << "---------- LLR calculation unit -----------------" << std::endl; 00161 os << "LLR_calc_unit table properties:" << std::endl; 00162 os << "The granularity in the LLR representation is " 00163 << pow2(static_cast<double>(-lcu.Dint1)) << std::endl; 00164 os << "The LLR scale factor is " << (1 << lcu.Dint1) << std::endl; 00165 os << "The largest LLR that can be represented is " 00166 << lcu.to_double(QLLR_MAX) << std::endl; 00167 os << "The table resolution is " 00168 << pow2(static_cast<double>(lcu.Dint3 - lcu.Dint1)) << std::endl; 00169 os << "The number of entries in the table is " << lcu.Dint2 << std::endl; 00170 os << "The tables truncates at the LLR value " 00171 << pow2(static_cast<double>(lcu.Dint3 - lcu.Dint1)) * lcu.Dint2 00172 << std::endl; 00173 os << "-------------------------------------------------" << std::endl; 00174 return os; 00175 } 00176 00177 }
Generated on Sat Apr 19 10:59:23 2008 for IT++ by Doxygen 1.5.5