36 int in_iterations, std::string in_metric,
double in_logmax_scale_factor,
40 iterations = in_iterations;
41 interleaver_size = interleaver_sequence.size();
42 Nuncoded = interleaver_size;
43 logmax_scale_factor = in_logmax_scale_factor;
44 adaptive_stop = in_adaptive_stop;
47 if (in_metric ==
"LOGMAX") {
50 else if (in_metric ==
"LOGMAP") {
53 else if (in_metric ==
"MAP") {
56 else if (in_metric ==
"TABLE") {
60 it_error(
"Turbo_Codec::set_parameters: The decoder metric must be either MAP, LOGMAP or LOGMAX");
63 if (logmax_scale_factor != 1.0) {
64 it_assert(metric ==
"LOGMAX",
"Turbo_Codec::set_parameters: logmax_scale_factor can only be used together with LOGMAX decoding");
70 n1 = gen1.length() - 1;
71 n2 = gen2.length() - 1;
75 m_tail = constraint_length - 1;
78 Ncoded = Nuncoded * n_tot + m_tail * (1 + n1) + m_tail * (1 + n2);
97 interleaver_size = interleaver_sequence.size();
98 Nuncoded = interleaver_size;
101 Ncoded = Nuncoded * n_tot + m_tail * (1 + n1) + m_tail * (1 + n2);
112 logmax_scale_factor = in_logmax_scale_factor;
115 if (in_metric ==
"LOGMAX") {
118 else if (in_metric ==
"LOGMAP") {
121 else if (in_metric ==
"MAP") {
124 else if (in_metric ==
"TABLE") {
128 it_error(
"Turbo_Codec::set_metric: The decoder metric must be either MAP, LOGMAP or LOGMAX");
137 iterations = in_iterations;
142 adaptive_stop = in_adaptive_stop;
161 int i, k, j, no_blocks;
163 bvec input_bits, in1, in2, tail1, tail2, out;
164 bmat parity1, parity2;
167 no_blocks = input.length() / Nuncoded;
168 output.set_size(no_blocks*Ncoded,
false);
174 for (i = 0; i < no_blocks; i++) {
177 input_bits = input.mid(i * Nuncoded, Nuncoded);
181 for (k = 0; k < Nuncoded; k++) {
182 output(count) = in1(k);
184 for (j = 0; j < n1; j++) { output(count) = parity1(k, j); count++; }
185 for (j = 0; j < n2; j++) { output(count) = parity2(k, j); count++; }
189 for (k = 0; k < m_tail; k++) {
190 output(count) = in1(Nuncoded + k);
192 for (j = 0; j < n1; j++) { output(count) = parity1(Nuncoded + k, j); count++; }
196 for (k = 0; k < m_tail; k++) {
197 output(count) = in2(Nuncoded + k);
199 for (j = 0; j < n2; j++) { output(count) = parity2(Nuncoded + k, j); count++; }
208 ivec nrof_used_iterations;
209 decode(received_signal, decoded_bits, nrof_used_iterations, true_bits);
213 const bvec &true_bits)
216 if ((n1 == 1) && (n2 == 1) && (metric !=
"MAP")) {
218 decode_n3(received_signal, decoded_bits, nrof_used_iterations, true_bits);
223 vec rec, rec_syst1, rec_syst2;
224 mat rec_parity1, rec_parity2;
226 int no_blocks, i, j, k, nrof_used_iterations_i;
228 bool CHECK_TRUE_BITS;
231 no_blocks = received_signal.length() / Ncoded;
232 decoded_bits.set_size(no_blocks * Nuncoded,
false);
233 decoded_bits_i.set_size(iterations, no_blocks * Nuncoded,
false);
234 rec_syst1.set_size(Nuncoded + m_tail,
false);
235 rec_syst2.set_size(Nuncoded + m_tail,
false);
237 rec_parity1.set_size(Nuncoded + m_tail, n1,
false);
238 rec_parity2.set_size(Nuncoded + m_tail, n2,
false);
239 nrof_used_iterations.set_size(no_blocks,
false);
242 if (true_bits.size() > 1) {
243 it_assert(true_bits.size() == (Nuncoded * no_blocks),
"Turbo_Codec::decode: Wrong size of input vectors");
244 CHECK_TRUE_BITS =
true;
247 CHECK_TRUE_BITS =
false;
254 for (i = 0; i < no_blocks; i++) {
257 for (k = 0; k < Nuncoded; k++) {
258 rec_syst1(k) = received_signal(count);
260 for (j = 0; j < n1; j++) { rec_parity1(k, j) = received_signal(count); count++; }
261 for (j = 0; j < n2; j++) { rec_parity2(k, j) = received_signal(count); count++; }
265 for (k = 0; k < m_tail; k++) {
266 rec_syst1(Nuncoded + k) = received_signal(count);
268 for (j = 0; j < n1; j++) { rec_parity1(Nuncoded + k, j) = received_signal(count); count++; }
272 for (k = 0; k < m_tail; k++) {
273 rec_syst2(Nuncoded + k) = received_signal(count);
275 for (j = 0; j < n2; j++) { rec_parity2(Nuncoded + k, j) = received_signal(count); count++; }
287 if (CHECK_TRUE_BITS) {
288 decode_block(rec_syst1, rec_syst2, rec_parity1, rec_parity2, decoded_bits_i,
289 nrof_used_iterations_i, true_bits.mid(i*Nuncoded, Nuncoded));
290 nrof_used_iterations(i) = nrof_used_iterations_i;
293 decode_block(rec_syst1, rec_syst2, rec_parity1, rec_parity2, decoded_bits_i, nrof_used_iterations_i);
294 nrof_used_iterations(i) = nrof_used_iterations_i;
298 decoded_bits.replace_mid(i*Nuncoded, decoded_bits_i.get_row(iterations - 1));
309 bvec tail1, tail2, interleaved_input;
312 it_assert(input.length() == Nuncoded,
"Turbo_Codec::encode_block: Parameter error in Nuncoded.");
315 tail1.set_size(m_tail,
false);
317 tail2.set_size(m_tail,
false);
319 parity1.set_size(Nuncoded + m_tail, n1,
false);
321 parity2.set_size(Nuncoded + m_tail, n2,
false);
323 interleaved_input.set_size(Nuncoded,
false);
324 interleaved_input.clear();
330 bit_interleaver.
interleave(input, interleaved_input);
333 rscc2.
encode_tail(interleaved_input, tail2, parity2);
336 in1 =
concat(input, tail1);
337 in2 =
concat(interleaved_input, tail2);
342 const mat &rec_parity2,
bmat &decoded_bits_i,
int &nrof_used_iterations_i,
343 const bvec &true_bits)
348 vec extrinsic_input, extrinsic_output, int_rec_syst1, int_rec_syst, tmp;
349 vec deint_rec_syst2, rec_syst, sub_rec_syst, Le12, Le21, Le12_int, Le21_int, L, tail1, tail2;
350 bool CHECK_TRUE_BITS, CONTINUE;
353 decoded_bits_i.set_size(iterations, Nuncoded,
false);
354 Le12.set_size(Nuncoded + m_tail,
false);
355 Le21.set_size(Nuncoded + m_tail,
false);
359 float_interleaver.
interleave(rec_syst1.left(interleaver_size), int_rec_syst1);
360 float_interleaver.
deinterleave(rec_syst2.left(interleaver_size), deint_rec_syst2);
363 rec_syst = rec_syst1.
left(interleaver_size) + deint_rec_syst2;
364 int_rec_syst = rec_syst2.
left(interleaver_size) + int_rec_syst1;
367 tail1 = rec_syst1.
right(m_tail);
368 tail2 = rec_syst2.
right(m_tail);
371 rec_syst =
concat(rec_syst, tail1);
372 int_rec_syst =
concat(int_rec_syst, tail2);
375 if (true_bits.size() > 1) {
376 it_assert(true_bits.size() == Nuncoded,
"Turbo_Codec::decode_block: Illegal size of input vector true_bits");
377 CHECK_TRUE_BITS =
true;
380 CHECK_TRUE_BITS =
false;
383 if (CHECK_TRUE_BITS) {
385 "Turbo_Codec::decode_block: You can not stop iterations both adaptively and on true bits");
389 nrof_used_iterations_i = iterations;
390 for (i = 0; i < iterations; i++) {
393 if (metric ==
"MAP") {
394 rscc1.
map_decode(rec_syst, rec_parity1, Le21, Le12,
true);
396 else if ((metric ==
"LOGMAX") || (metric ==
"LOGMAP") || (metric ==
"TABLE")) {
397 rscc1.
log_decode(rec_syst, rec_parity1, Le21, Le12,
true, metric);
398 if (logmax_scale_factor != 1.0) {
399 Le12 *= logmax_scale_factor;
403 it_error(
"Turbo_Codec::decode_block: Illegal metric value");
407 float_interleaver.
interleave(Le12.left(interleaver_size), tmp);
408 Le12_int =
concat(tmp,
zeros(Le12.size() - interleaver_size));
411 if (metric ==
"MAP") {
412 rscc2.
map_decode(int_rec_syst, rec_parity2, Le12_int, Le21_int,
true);
414 else if ((metric ==
"LOGMAX") || (metric ==
"LOGMAP") || (metric ==
"TABLE")) {
415 rscc2.
log_decode(int_rec_syst, rec_parity2, Le12_int, Le21_int,
true, metric);
416 if (logmax_scale_factor != 1.0) {
417 Le21_int *= logmax_scale_factor;
421 it_error(
"Turbo_Codec::decode_block: Illegal metric value");
425 float_interleaver.
deinterleave(Le21_int.left(interleaver_size), tmp);
426 Le21 =
concat(tmp,
zeros(Le21_int.size() - interleaver_size));
429 L = rec_syst + Le21 + Le12;
431 for (l = 0; l < Nuncoded; l++) {
432 (L(l) > 0.0) ? (decoded_bits_i(i, count) =
bin(0)) : (decoded_bits_i(i, count) =
bin(1));
438 if (i < (iterations - 1)) {
440 if (CHECK_TRUE_BITS) {
442 for (k = 0; k < Nuncoded; k++) {
if (true_bits(k) != decoded_bits_i(i, k)) { CONTINUE =
true;
break; } }
445 if ((adaptive_stop) && (i > 0)) {
447 for (k = 0; k < Nuncoded; k++) {
if (decoded_bits_i(i - 1, k) != decoded_bits_i(i, k)) { CONTINUE =
true;
break; } }
453 if (CONTINUE ==
false) {
455 for (k = (i + 1); k < iterations; k++) {
456 decoded_bits_i.set_row(k, decoded_bits_i.get_row(i));
457 nrof_used_iterations_i = i + 1;
466 void Turbo_Codec::decode_n3(
const vec &received_signal, bvec &decoded_bits, ivec &nrof_used_iterations,
467 const bvec &true_bits)
470 vec rec, rec_syst1, int_rec_syst1, rec_syst2;
471 vec rec_parity1, rec_parity2;
472 vec extrinsic_input, extrinsic_output, Le12, Le21, Le12_int, Le21_int, L;
473 bvec temp_decoded_bits;
474 int no_blocks, i, j, k, l, nrof_used_iterations_i;
475 int count, count_out;
476 bool CHECK_TRUE_BITS, CONTINUE;
479 no_blocks = received_signal.length() / Ncoded;
480 decoded_bits.set_size(no_blocks * Nuncoded,
false);
481 rec_syst1.set_size(Nuncoded + m_tail,
false);
482 rec_syst2.set_size(Nuncoded + m_tail,
false);
484 rec_parity1.set_size(Nuncoded + m_tail,
false);
485 rec_parity2.set_size(Nuncoded + m_tail,
false);
486 temp_decoded_bits.set_size(Nuncoded,
false);
487 decoded_bits_previous_iteration.set_size(Nuncoded,
false);
488 nrof_used_iterations.set_size(no_blocks,
false);
491 Le12.set_size(Nuncoded,
false);
492 Le21.set_size(Nuncoded,
false);
499 if (true_bits.size() > 1) {
500 it_assert(true_bits.size() == Nuncoded*no_blocks,
"Turbo_Codec::decode_n3: Illegal size of input vector true_bits");
501 CHECK_TRUE_BITS =
true;
504 CHECK_TRUE_BITS =
false;
507 if (CHECK_TRUE_BITS) {
509 "Turbo_Codec::decode_block: You can not stop iterations both adaptively and on true bits");
513 for (i = 0; i < no_blocks; i++) {
519 for (k = 0; k < Nuncoded; k++) {
520 rec_syst1(k) = received_signal(count);
522 rec_parity1(k) = received_signal(count);
524 rec_parity2(k) = received_signal(count);
529 for (k = 0; k < m_tail; k++) {
530 rec_syst1(Nuncoded + k) = received_signal(count);
532 rec_parity1(Nuncoded + k) = received_signal(count);
537 for (k = 0; k < m_tail; k++) {
538 rec_syst2(Nuncoded + k) = received_signal(count);
540 rec_parity2(Nuncoded + k) = received_signal(count);
544 float_interleaver.
interleave(rec_syst1.left(Nuncoded), int_rec_syst1);
557 nrof_used_iterations_i = iterations;
558 for (j = 0; j < iterations; j++) {
560 rscc1.
log_decode_n2(rec_syst1, rec_parity1, Le21, Le12,
true, metric);
561 if (logmax_scale_factor != 1.0) { Le12 *= logmax_scale_factor; }
564 rscc2.
log_decode_n2(rec_syst2, rec_parity2, Le12_int, Le21_int,
true, metric);
565 if (logmax_scale_factor != 1.0) { Le21_int *= logmax_scale_factor; }
569 L = rec_syst1.
left(Nuncoded) + Le21.
left(Nuncoded) + Le12.
left(Nuncoded);
570 for (l = 0; l < Nuncoded; l++) {(L(l) > 0.0) ? (temp_decoded_bits(l) = bin(0)) : (temp_decoded_bits(l) = bin(1)); }
571 if (j == 0) { decoded_bits_previous_iteration = temp_decoded_bits; }
573 if (temp_decoded_bits == decoded_bits_previous_iteration) {
576 else if (j < (iterations - 1)) {
577 decoded_bits_previous_iteration = temp_decoded_bits;
582 if (CHECK_TRUE_BITS) {
583 L = rec_syst1.left(Nuncoded) + Le21.left(Nuncoded) + Le12.left(Nuncoded);
584 for (l = 0; l < Nuncoded; l++) {(L(l) > 0.0) ? (temp_decoded_bits(l) = bin(0)) : (temp_decoded_bits(l) = bin(1)); }
585 if (temp_decoded_bits == true_bits.mid(i*Nuncoded, Nuncoded)) {
590 if (CONTINUE ==
false) { nrof_used_iterations_i = j + 1;
break; }
595 L = rec_syst1.left(Nuncoded) + Le21.left(Nuncoded) + Le12.left(Nuncoded);
596 for (l = 0; l < Nuncoded; l++) {
597 (L(l) > 0.0) ? (decoded_bits(count_out) = bin(0)) : (decoded_bits(count_out) = bin(1));
601 nrof_used_iterations(i) = nrof_used_iterations_i;
609 const int MAX_INTERLEAVER_SIZE = 5114;
610 const int MIN_INTERLEAVER_SIZE = 40;
622 ivec primes,
roots, Pat1, Pat2, Pat3, Pat4, Isort;
623 int i, j, qj, temp, row, col, index, count;
625 if (interleaver_size > MAX_INTERLEAVER_SIZE) {
627 I = sort_index(
randu(interleaver_size));
637 it_assert(interleaver_size <= MAX_INTERLEAVER_SIZE,
"wcdma_turbo_interleaver_sequence: The interleaver size is to large");
638 it_assert(interleaver_size >= MIN_INTERLEAVER_SIZE,
"wcdma_turbo_interleaver_sequence: The interleaver size is to small");
640 K = interleaver_size;
643 primes =
"2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211 223 227 229 233 239 241 251 257";
644 roots =
"0 0 0 3 2 2 3 2 5 2 3 2 6 3 5 2 2 2 2 7 5 3 2 3 5 2 5 2 6 3 3 2 3 2 2 6 5 2 5 2 2 2 19 5 2 3 2 3 2 6 3 7 7 6 3";
647 if ((K >= 40) && (K <= 159)) {
650 else if (((K >= 160) && (K <= 200)) || ((K >= 481) && (K <= 530))) {
658 if ((K >= 481) && (K <= 530)) {
665 for (i = 0; i < primes.length(); i++) {
666 if ((
double(primes(i) + 1) -
double(K) /
double(R)) >= 0.0) {
673 if ((
double(p) -
double(K) /
double(R)) >= 0.0) {
674 if ((
double(p) - 1.0 -
double(K) /
double(R)) >= 0.0) {
687 s.set_size(p - 1,
false);
690 for (i = 1; i <= (p - 2); i++) {
691 s(i) =
mod(v * s(i - 1), p);
696 q.set_size(R,
false);
699 for (j = 1; j <= (R - 1); j++) {
700 for (i = 0; i < primes.length(); i++) {
702 if ((qj > 6) && (qj > q(j - 1))) {
703 if (
gcd(qj, p - 1) == 1) {
712 Pat1 =
"19 9 14 4 0 2 5 7 12 18 10 8 13 17 3 1 16 6 15 11";
713 Pat2 =
"19 9 14 4 0 2 5 7 12 18 16 13 17 15 3 1 6 11 8 10";
714 Pat3 =
"9 8 7 6 5 4 3 2 1 0";
722 else if (K >= 3161) {
725 else if (K >= 2481) {
728 else if (K >= 2281) {
749 r.set_size(R,
false);
751 for (j = 0; j <= (R - 1); j++) {
757 U.set_size(R, C,
false);
760 for (j = 0; j <= (R - 1); j++) {
761 for (i = 0; i <= (p - 2); i++) {
762 U(j, i) = s(
mod(i * r(j), p - 1));
767 else if (C == (p + 1)) {
768 for (j = 0; j <= (R - 1); j++) {
769 for (i = 0; i <= (p - 2); i++) {
770 U(j, i) = s(
mod(i * r(j), p - 1));
777 U(R - 1, p) = U(R - 1, 0);
781 else if (C == (p - 1)) {
782 for (j = 0; j <= (R - 1); j++) {
783 for (i = 0; i <= (p - 2); i++) {
784 U(j, i) = s(
mod(i * r(j), p - 1)) - 1;
790 I.set_size(K,
false);
793 for (i = 0; i < C; i++) {
794 for (j = 0; j < R; j++) {
797 index = row * C + col;