IT++ Logo
llr.cpp
Go to the documentation of this file.
1 
30 #include <itpp/comm/llr.h>
31 
32 
33 namespace itpp
34 {
35 
37 {
39 }
40 
41 LLR_calc_unit::LLR_calc_unit(short int d1, short int d2, short int d3)
42 {
43  init_llr_tables(d1, d2, d3);
44 }
45 
47 {
48  ivec r(3);
49  r(0) = Dint1;
50  r(1) = Dint2;
51  r(2) = Dint3;
52  return r;
53 }
54 
55 void LLR_calc_unit::init_llr_tables(short int d1, short int d2, short int d3)
56 {
57  Dint1 = d1; // 1<<Dint1 determines how integral LLRs relate to real LLRs (to_double=(1<<Dint)*int_llr)
58  Dint2 = d2; // number of entries in table for LLR operations
59  Dint3 = d3; // table resolution is 2^(-(Dint1-Dint3))
60  logexp_table = construct_logexp_table();
61 }
62 
63 ivec LLR_calc_unit::construct_logexp_table()
64 {
65  ivec result(Dint2);
66  for (int i = 0; i < Dint2; i++) {
67  double x = pow2(static_cast<double>(Dint3 - Dint1)) * i;
68  result(i) = to_qllr(std::log(1 + std::exp(-x)));
69  }
70  it_assert(length(result) == Dint2, "Ldpc_codec::construct_logexp_table()");
71 
72  return result;
73 }
74 
75 QLLRvec LLR_calc_unit::to_qllr(const vec &l) const
76 {
77  int n = length(l);
78  ivec result(n);
79  for (int i = 0; i < n; i++) {
80  result.set(i, to_qllr(l(i)));
81  }
82  return result;
83 }
84 
85 vec LLR_calc_unit::to_double(const QLLRvec &l) const
86 {
87  int n = length(l);
88  vec result(n);
89  for (int i = 0; i < n; i++) {
90  result.set(i, to_double(l(i)));
91  }
92  return result;
93 }
94 
95 QLLRmat LLR_calc_unit::to_qllr(const mat &l) const
96 {
97  int m = l.rows();
98  int n = l.cols();
99  imat result(m, n);
100  for (int i = 0; i < m; i++) {
101  for (int j = 0; j < n; j++) {
102  result.set(i, j, to_qllr(l(i, j)));
103  }
104  }
105  return result;
106 }
107 
109 {
110  int m = l.rows();
111  int n = l.cols();
112  mat result(m, n);
113  for (int i = 0; i < m; i++) {
114  for (int j = 0; j < n; j++) {
115  result.set(i, j, to_double(l(i, j)));
116  }
117  }
118  return result;
119 }
120 
121 // This function used to be inline, but in my experiments,
122 // the non-inlined version was actually faster /Martin Senst
124 {
125  QLLR a_abs = (a > 0 ? a : -a);
126  QLLR b_abs = (b > 0 ? b : -b);
127  QLLR minabs = (a_abs > b_abs ? b_abs : a_abs);
128  QLLR term1 = (a > 0 ? (b > 0 ? minabs : -minabs)
129  : (b > 0 ? -minabs : minabs));
130 
131  if (Dint2 == 0) { // logmax approximation - avoid looking into empty table
132  // Don't abort when overflowing, just saturate the QLLR
133  if (term1 > QLLR_MAX) {
134  it_info_debug("LLR_calc_unit::Boxplus(): LLR overflow");
135  return QLLR_MAX;
136  }
137  if (term1 < -QLLR_MAX) {
138  it_info_debug("LLR_calc_unit::Boxplus(): LLR overflow");
139  return -QLLR_MAX;
140  }
141  return term1;
142  }
143 
144  QLLR apb = a + b;
145  QLLR term2 = logexp((apb > 0 ? apb : -apb));
146  QLLR amb = a - b;
147  QLLR term3 = logexp((amb > 0 ? amb : -amb));
148  QLLR result = term1 + term2 - term3;
149 
150  // Don't abort when overflowing, just saturate the QLLR
151  if (result > QLLR_MAX) {
152  it_info_debug("LLR_calc_unit::Boxplus() LLR overflow");
153  return QLLR_MAX;
154  }
155  if (result < -QLLR_MAX) {
156  it_info_debug("LLR_calc_unit::Boxplus() LLR overflow");
157  return -QLLR_MAX;
158  }
159  return result;
160 }
161 
162 std::ostream &operator<<(std::ostream &os, const LLR_calc_unit &lcu)
163 {
164  os << "---------- LLR calculation unit -----------------" << std::endl;
165  os << "LLR_calc_unit table properties:" << std::endl;
166  os << "The granularity in the LLR representation is "
167  << pow2(static_cast<double>(-lcu.Dint1)) << std::endl;
168  os << "The LLR scale factor is " << (1 << lcu.Dint1) << std::endl;
169  os << "The largest LLR that can be represented is "
170  << lcu.to_double(QLLR_MAX) << std::endl;
171  os << "The table resolution is "
172  << pow2(static_cast<double>(lcu.Dint3 - lcu.Dint1)) << std::endl;
173  os << "The number of entries in the table is " << lcu.Dint2 << std::endl;
174  os << "The tables truncates at the LLR value "
175  << pow2(static_cast<double>(lcu.Dint3 - lcu.Dint1)) * lcu.Dint2
176  << std::endl;
177  os << "-------------------------------------------------" << std::endl;
178  return os;
179 }
180 
181 }
SourceForge Logo

Generated on Sat May 25 2013 16:32:21 for IT++ by Doxygen 1.8.2