00001 00030 #include <itpp/comm/turbo.h> 00031 00032 00033 namespace itpp 00034 { 00035 00036 void Turbo_Codec::set_parameters(ivec gen1, ivec gen2, int constraint_length, const ivec &interleaver_sequence, 00037 int in_iterations, std::string in_metric, double in_logmax_scale_factor, 00038 bool in_adaptive_stop, LLR_calc_unit in_llrcalc) 00039 { 00040 //Set the input parameters: 00041 iterations = in_iterations; 00042 interleaver_size = interleaver_sequence.size(); 00043 Nuncoded = interleaver_size; 00044 logmax_scale_factor = in_logmax_scale_factor; 00045 adaptive_stop = in_adaptive_stop; 00046 00047 //Check the decoding metric 00048 if (in_metric == "LOGMAX") { 00049 metric = "LOGMAX"; 00050 } 00051 else if (in_metric == "LOGMAP") { 00052 metric = "LOGMAP"; 00053 } 00054 else if (in_metric == "MAP") { 00055 metric = "MAP"; 00056 } 00057 else if (in_metric == "TABLE") { 00058 metric = "TABLE"; 00059 } 00060 else { 00061 it_error("Turbo_Codec::set_parameters: The decoder metric must be either MAP, LOGMAP or LOGMAX"); 00062 } 00063 00064 if (logmax_scale_factor != 1.0) { 00065 it_assert(metric == "LOGMAX", "Turbo_Codec::set_parameters: logmax_scale_factor can only be used together with LOGMAX decoding"); 00066 } 00067 00068 //The RSC Encoders: 00069 rscc1.set_generator_polynomials(gen1, constraint_length); 00070 rscc2.set_generator_polynomials(gen2, constraint_length); 00071 n1 = gen1.length() - 1; //Number of parity bits from rscc1 00072 n2 = gen2.length() - 1; //Number of parity bits from rscc2 00073 n_tot = 1 + n1 + n2; //Total number of parity bits and systematic bits 00074 00075 //Set the number of tail bits: 00076 m_tail = constraint_length - 1; 00077 00078 //Calculate the number of coded bits per code-block: 00079 Ncoded = Nuncoded * n_tot + m_tail * (1 + n1) + m_tail * (1 + n2); 00080 00081 //Set the interleaver sequence 00082 bit_interleaver.set_interleaver_depth(interleaver_size); 00083 float_interleaver.set_interleaver_depth(interleaver_size); 00084 bit_interleaver.set_interleaver_sequence(interleaver_sequence); 00085 float_interleaver.set_interleaver_sequence(interleaver_sequence); 00086 00087 //Default value of the channel reliability scaling factor is 1 00088 Lc = 1.0; 00089 00090 // LLR algebra table 00091 rscc1.set_llrcalc(in_llrcalc); 00092 rscc2.set_llrcalc(in_llrcalc); 00093 00094 } 00095 00096 void Turbo_Codec::set_interleaver(const ivec &interleaver_sequence) 00097 { 00098 interleaver_size = interleaver_sequence.size(); 00099 Nuncoded = interleaver_size; 00100 00101 //Calculate the number of coded bits per code-block: 00102 Ncoded = Nuncoded * n_tot + m_tail * (1 + n1) + m_tail * (1 + n2); 00103 00104 //Set the interleaver sequence 00105 bit_interleaver.set_interleaver_depth(interleaver_size); 00106 float_interleaver.set_interleaver_depth(interleaver_size); 00107 bit_interleaver.set_interleaver_sequence(interleaver_sequence); 00108 float_interleaver.set_interleaver_sequence(interleaver_sequence); 00109 } 00110 00111 void Turbo_Codec::set_metric(std::string in_metric, double in_logmax_scale_factor, LLR_calc_unit in_llrcalc) 00112 { 00113 logmax_scale_factor = in_logmax_scale_factor; 00114 00115 //Check the decoding metric 00116 if (in_metric == "LOGMAX") { 00117 metric = "LOGMAX"; 00118 } 00119 else if (in_metric == "LOGMAP") { 00120 metric = "LOGMAP"; 00121 } 00122 else if (in_metric == "MAP") { 00123 metric = "MAP"; 00124 } 00125 else if (in_metric == "TABLE") { 00126 metric = "TABLE"; 00127 } 00128 else { 00129 it_error("Turbo_Codec::set_metric: The decoder metric must be either MAP, LOGMAP or LOGMAX"); 00130 } 00131 00132 rscc1.set_llrcalc(in_llrcalc); 00133 rscc2.set_llrcalc(in_llrcalc); 00134 } 00135 00136 void Turbo_Codec::set_iterations(int in_iterations) 00137 { 00138 iterations = in_iterations; 00139 } 00140 00141 void Turbo_Codec::set_adaptive_stop(bool in_adaptive_stop) 00142 { 00143 adaptive_stop = in_adaptive_stop; 00144 } 00145 00146 void Turbo_Codec::set_awgn_channel_parameters(double in_Ec, double in_N0) 00147 { 00148 Ec = in_Ec; 00149 N0 = in_N0; 00150 Lc = 4.0 * std::sqrt(Ec) / N0; 00151 } 00152 00153 void Turbo_Codec::set_scaling_factor(double in_Lc) 00154 { 00155 Lc = in_Lc; 00156 } 00157 00158 00159 void Turbo_Codec::encode(const bvec &input, bvec &output) 00160 { 00161 //Local variables: 00162 int i, k, j, no_blocks; 00163 int count; 00164 bvec input_bits, in1, in2, tail1, tail2, out; 00165 bmat parity1, parity2; 00166 00167 //Initializations: 00168 no_blocks = input.length() / Nuncoded; 00169 output.set_size(no_blocks*Ncoded, false); 00170 00171 //Set the bit counter to zero: 00172 count = 0; 00173 00174 //Encode all code blocks: 00175 for (i = 0; i < no_blocks; i++) { 00176 00177 //Encode one block 00178 input_bits = input.mid(i * Nuncoded, Nuncoded); 00179 encode_block(input_bits, in1, in2, parity1, parity2); 00180 00181 //The data part: 00182 for (k = 0; k < Nuncoded; k++) { 00183 output(count) = in1(k); 00184 count++; //Systematic bits 00185 for (j = 0; j < n1; j++) { output(count) = parity1(k, j); count++; } //Parity-1 bits 00186 for (j = 0; j < n2; j++) { output(count) = parity2(k, j); count++; } //Parity-2 bits 00187 } 00188 00189 //The first tail: 00190 for (k = 0; k < m_tail; k++) { 00191 output(count) = in1(Nuncoded + k); 00192 count++; //First systematic tail bit 00193 for (j = 0; j < n1; j++) { output(count) = parity1(Nuncoded + k, j); count++; } //Parity-1 tail bits 00194 } 00195 00196 //The second tail: 00197 for (k = 0; k < m_tail; k++) { 00198 output(count) = in2(Nuncoded + k); 00199 count++; //Second systematic tail bit 00200 for (j = 0; j < n2; j++) { output(count) = parity2(Nuncoded + k, j); count++; } //Parity-2 tail bits 00201 } 00202 00203 } 00204 00205 } 00206 00207 void Turbo_Codec::decode(const vec &received_signal, bvec &decoded_bits, const bvec &true_bits) 00208 { 00209 ivec nrof_used_iterations; 00210 decode(received_signal, decoded_bits, nrof_used_iterations, true_bits); 00211 } 00212 00213 void Turbo_Codec::decode(const vec &received_signal, bvec &decoded_bits, ivec &nrof_used_iterations, 00214 const bvec &true_bits) 00215 { 00216 00217 if ((n1 == 1) && (n2 == 1) && (metric != "MAP")) { 00218 //This is a speed optimized decoder for R=1/3 (log domain metrics only) 00219 decode_n3(received_signal, decoded_bits, nrof_used_iterations, true_bits); 00220 } 00221 else { 00222 00223 //Local variables: 00224 vec rec, rec_syst1, rec_syst2; 00225 mat rec_parity1, rec_parity2; 00226 bmat decoded_bits_i; 00227 int no_blocks, i, j, k, nrof_used_iterations_i; 00228 int count; 00229 bool CHECK_TRUE_BITS; 00230 00231 //Initilaizations: 00232 no_blocks = received_signal.length() / Ncoded; 00233 decoded_bits.set_size(no_blocks * Nuncoded, false); 00234 decoded_bits_i.set_size(iterations, no_blocks * Nuncoded, false); 00235 rec_syst1.set_size(Nuncoded + m_tail, false); 00236 rec_syst2.set_size(Nuncoded + m_tail, false); 00237 rec_syst2.clear(); 00238 rec_parity1.set_size(Nuncoded + m_tail, n1, false); 00239 rec_parity2.set_size(Nuncoded + m_tail, n2, false); 00240 nrof_used_iterations.set_size(no_blocks, false); 00241 00242 //Check the vector true_bits: 00243 if (true_bits.size() > 1) { 00244 it_assert(true_bits.size() == (Nuncoded * no_blocks), "Turbo_Codec::decode: Wrong size of input vectors"); 00245 CHECK_TRUE_BITS = true; 00246 } 00247 else { 00248 CHECK_TRUE_BITS = false; 00249 } 00250 00251 //Set the bit counter to zero: 00252 count = 0; 00253 00254 //Itterate over all received code blocks: 00255 for (i = 0; i < no_blocks; i++) { 00256 00257 //The data part: 00258 for (k = 0; k < Nuncoded; k++) { 00259 rec_syst1(k) = received_signal(count); 00260 count++; //Systematic bit 00261 for (j = 0; j < n1; j++) { rec_parity1(k, j) = received_signal(count); count++; } //Parity-1 bits 00262 for (j = 0; j < n2; j++) { rec_parity2(k, j) = received_signal(count); count++; } //Parity-2 bits 00263 } 00264 00265 //The first tail: 00266 for (k = 0; k < m_tail; k++) { 00267 rec_syst1(Nuncoded + k) = received_signal(count); 00268 count++; //Tail 1 systematic bit 00269 for (j = 0; j < n1; j++) { rec_parity1(Nuncoded + k, j) = received_signal(count); count++; } //Tail 1 parity-1 bits 00270 } 00271 00272 //The second tail: 00273 for (k = 0; k < m_tail; k++) { 00274 rec_syst2(Nuncoded + k) = received_signal(count); 00275 count++; //Tail2 systematic bit 00276 for (j = 0; j < n2; j++) { rec_parity2(Nuncoded + k, j) = received_signal(count); count++; } //Tali2 parity-2 bits 00277 } 00278 00279 //Scale the input data if necessary: 00280 if (Lc != 1.0) { 00281 rec_syst1 *= Lc; 00282 rec_syst2 *= Lc; 00283 rec_parity1 *= Lc; 00284 rec_parity2 *= Lc; 00285 } 00286 00287 //Decode the block: 00288 if (CHECK_TRUE_BITS) { 00289 decode_block(rec_syst1, rec_syst2, rec_parity1, rec_parity2, decoded_bits_i, 00290 nrof_used_iterations_i, true_bits.mid(i*Nuncoded, Nuncoded)); 00291 nrof_used_iterations(i) = nrof_used_iterations_i; 00292 } 00293 else { 00294 decode_block(rec_syst1, rec_syst2, rec_parity1, rec_parity2, decoded_bits_i, nrof_used_iterations_i); 00295 nrof_used_iterations(i) = nrof_used_iterations_i; 00296 } 00297 00298 //Put the decoded bits in the output vector: 00299 decoded_bits.replace_mid(i*Nuncoded, decoded_bits_i.get_row(iterations - 1)); 00300 00301 } 00302 00303 } 00304 00305 } 00306 00307 void Turbo_Codec::encode_block(const bvec &input, bvec &in1, bvec &in2, bmat &parity1, bmat &parity2) 00308 { 00309 //Local variables: 00310 bvec tail1, tail2, interleaved_input; 00311 00312 //Error check: 00313 it_assert(input.length() == Nuncoded, "Turbo_Codec::encode_block: Parameter error in Nuncoded."); 00314 00315 //Initializations: 00316 tail1.set_size(m_tail, false); 00317 tail1.clear(); 00318 tail2.set_size(m_tail, false); 00319 tail2.clear(); 00320 parity1.set_size(Nuncoded + m_tail, n1, false); 00321 parity1.clear(); 00322 parity2.set_size(Nuncoded + m_tail, n2, false); 00323 parity2.clear(); 00324 interleaved_input.set_size(Nuncoded, false); 00325 interleaved_input.clear(); 00326 00327 //The first encoder: 00328 rscc1.encode_tail(input, tail1, parity1); 00329 00330 //The interleaver: 00331 bit_interleaver.interleave(input, interleaved_input); 00332 00333 //The second encoder: 00334 rscc2.encode_tail(interleaved_input, tail2, parity2); 00335 00336 //The input vectors used to the two constituent encoders: 00337 in1 = concat(input, tail1); 00338 in2 = concat(interleaved_input, tail2); 00339 00340 } 00341 00342 void Turbo_Codec::decode_block(const vec &rec_syst1, const vec &rec_syst2, const mat &rec_parity1, 00343 const mat &rec_parity2, bmat &decoded_bits_i, int &nrof_used_iterations_i, 00344 const bvec &true_bits) 00345 { 00346 //Local variables: 00347 int i; 00348 int count, l, k; 00349 vec extrinsic_input, extrinsic_output, int_rec_syst1, int_rec_syst, tmp; 00350 vec deint_rec_syst2, rec_syst, sub_rec_syst, Le12, Le21, Le12_int, Le21_int, L, tail1, tail2; 00351 bool CHECK_TRUE_BITS, CONTINUE; 00352 00353 //Size initializations: 00354 decoded_bits_i.set_size(iterations, Nuncoded, false); 00355 Le12.set_size(Nuncoded + m_tail, false); 00356 Le21.set_size(Nuncoded + m_tail, false); 00357 Le21.zeros(); 00358 00359 //Calculate the interleaved and the deinterleaved sequences: 00360 float_interleaver.interleave(rec_syst1.left(interleaver_size), int_rec_syst1); 00361 float_interleaver.deinterleave(rec_syst2.left(interleaver_size), deint_rec_syst2); 00362 00363 //Combine the results from rec_syst1 and rec_syst2 (in case some bits are transmitted several times) 00364 rec_syst = rec_syst1.left(interleaver_size) + deint_rec_syst2; 00365 int_rec_syst = rec_syst2.left(interleaver_size) + int_rec_syst1; 00366 00367 //Get the two tails 00368 tail1 = rec_syst1.right(m_tail); 00369 tail2 = rec_syst2.right(m_tail); 00370 00371 //Form the input vectors (including tails) to the two decoders: 00372 rec_syst = concat(rec_syst, tail1); 00373 int_rec_syst = concat(int_rec_syst, tail2); 00374 00375 // Check the vector true_bits 00376 if (true_bits.size() > 1) { 00377 it_assert(true_bits.size() == Nuncoded, "Turbo_Codec::decode_block: Illegal size of input vector true_bits"); 00378 CHECK_TRUE_BITS = true; 00379 } 00380 else { 00381 CHECK_TRUE_BITS = false; 00382 } 00383 00384 if (CHECK_TRUE_BITS) { 00385 it_assert(adaptive_stop == false, 00386 "Turbo_Codec::decode_block: You can not stop iterations both adaptively and on true bits"); 00387 } 00388 00389 // Do the iterative decoding: 00390 nrof_used_iterations_i = iterations; 00391 for (i = 0; i < iterations; i++) { 00392 00393 // Decode Code 1 00394 if (metric == "MAP") { 00395 rscc1.map_decode(rec_syst, rec_parity1, Le21, Le12, true); 00396 } 00397 else if ((metric == "LOGMAX") || (metric == "LOGMAP") || (metric == "TABLE")) { 00398 rscc1.log_decode(rec_syst, rec_parity1, Le21, Le12, true, metric); 00399 if (logmax_scale_factor != 1.0) { 00400 Le12 *= logmax_scale_factor; 00401 } 00402 } 00403 else { 00404 it_error("Turbo_Codec::decode_block: Illegal metric value"); 00405 } 00406 00407 // Interleave the extrinsic information: 00408 float_interleaver.interleave(Le12.left(interleaver_size), tmp); 00409 Le12_int = concat(tmp, zeros(Le12.size() - interleaver_size)); 00410 00411 // Decode Code 2 00412 if (metric == "MAP") { 00413 rscc2.map_decode(int_rec_syst, rec_parity2, Le12_int, Le21_int, true); 00414 } 00415 else if ((metric == "LOGMAX") || (metric == "LOGMAP") || (metric == "TABLE")) { 00416 rscc2.log_decode(int_rec_syst, rec_parity2, Le12_int, Le21_int, true, metric); 00417 if (logmax_scale_factor != 1.0) { 00418 Le21_int *= logmax_scale_factor; 00419 } 00420 } 00421 else { 00422 it_error("Turbo_Codec::decode_block: Illegal metric value"); 00423 } 00424 00425 // De-interleave the extrinsic information: 00426 float_interleaver.deinterleave(Le21_int.left(interleaver_size), tmp); 00427 Le21 = concat(tmp, zeros(Le21_int.size() - interleaver_size)); 00428 00429 // Take bit decisions 00430 L = rec_syst + Le21 + Le12; 00431 count = 0; 00432 for (l = 0; l < Nuncoded; l++) { 00433 (L(l) > 0.0) ? (decoded_bits_i(i, count) = bin(0)) : (decoded_bits_i(i, count) = bin(1)); 00434 count++; 00435 } 00436 00437 //Check if it is possible to stop iterating early: 00438 CONTINUE = true; 00439 if (i < (iterations - 1)) { 00440 00441 if (CHECK_TRUE_BITS) { 00442 CONTINUE = false; 00443 for (k = 0; k < Nuncoded; k++) { if (true_bits(k) != decoded_bits_i(i, k)) { CONTINUE = true; break; } } 00444 } 00445 00446 if ((adaptive_stop) && (i > 0)) { 00447 CONTINUE = false; 00448 for (k = 0; k < Nuncoded; k++) { if (decoded_bits_i(i - 1, k) != decoded_bits_i(i, k)) { CONTINUE = true; break; } } 00449 } 00450 00451 } 00452 00453 //Check if iterations shall continue: 00454 if (CONTINUE == false) { 00455 //Copy the results from current iteration to all following iterations: 00456 for (k = (i + 1); k < iterations; k++) { 00457 decoded_bits_i.set_row(k, decoded_bits_i.get_row(i)); 00458 nrof_used_iterations_i = i + 1; 00459 } 00460 break; 00461 } 00462 00463 } 00464 00465 } 00466 00467 void Turbo_Codec::decode_n3(const vec &received_signal, bvec &decoded_bits, ivec &nrof_used_iterations, 00468 const bvec &true_bits) 00469 { 00470 //Local variables: 00471 vec rec, rec_syst1, int_rec_syst1, rec_syst2; 00472 vec rec_parity1, rec_parity2; 00473 vec extrinsic_input, extrinsic_output, Le12, Le21, Le12_int, Le21_int, L; 00474 bvec temp_decoded_bits; 00475 int no_blocks, i, j, k, l, nrof_used_iterations_i; 00476 int count, count_out; 00477 bool CHECK_TRUE_BITS, CONTINUE; 00478 00479 //Initializations: 00480 no_blocks = received_signal.length() / Ncoded; 00481 decoded_bits.set_size(no_blocks * Nuncoded, false); 00482 rec_syst1.set_size(Nuncoded + m_tail, false); 00483 rec_syst2.set_size(Nuncoded + m_tail, false); 00484 rec_syst2.clear(); 00485 rec_parity1.set_size(Nuncoded + m_tail, false); 00486 rec_parity2.set_size(Nuncoded + m_tail, false); 00487 temp_decoded_bits.set_size(Nuncoded, false); 00488 decoded_bits_previous_iteration.set_size(Nuncoded, false); 00489 nrof_used_iterations.set_size(no_blocks, false); 00490 00491 //Size initializations: 00492 Le12.set_size(Nuncoded, false); 00493 Le21.set_size(Nuncoded, false); 00494 00495 //Set the bit counter to zero: 00496 count = 0; 00497 count_out = 0; 00498 00499 // Check the vector true_bits 00500 if (true_bits.size() > 1) { 00501 it_assert(true_bits.size() == Nuncoded*no_blocks, "Turbo_Codec::decode_n3: Illegal size of input vector true_bits"); 00502 CHECK_TRUE_BITS = true; 00503 } 00504 else { 00505 CHECK_TRUE_BITS = false; 00506 } 00507 00508 if (CHECK_TRUE_BITS) { 00509 it_assert(adaptive_stop == false, 00510 "Turbo_Codec::decode_block: You can not stop iterations both adaptively and on true bits"); 00511 } 00512 00513 //Iterate over all received code blocks: 00514 for (i = 0; i < no_blocks; i++) { 00515 00516 //Reset extrinsic data: 00517 Le21.zeros(); 00518 00519 //The data part: 00520 for (k = 0; k < Nuncoded; k++) { 00521 rec_syst1(k) = received_signal(count); 00522 count++; //Systematic bit 00523 rec_parity1(k) = received_signal(count); 00524 count++; //Parity-1 bits 00525 rec_parity2(k) = received_signal(count); 00526 count++; //Parity-2 bits 00527 } 00528 00529 //The first tail: 00530 for (k = 0; k < m_tail; k++) { 00531 rec_syst1(Nuncoded + k) = received_signal(count); 00532 count++; //Tail 1 systematic bit 00533 rec_parity1(Nuncoded + k) = received_signal(count); 00534 count++; //Tail 1 parity-1 bits 00535 } 00536 00537 //The second tail: 00538 for (k = 0; k < m_tail; k++) { 00539 rec_syst2(Nuncoded + k) = received_signal(count); 00540 count++; //Tail2 systematic bit 00541 rec_parity2(Nuncoded + k) = received_signal(count); 00542 count++; //Tali2 parity-2 bits 00543 } 00544 00545 float_interleaver.interleave(rec_syst1.left(Nuncoded), int_rec_syst1); 00546 rec_syst2.replace_mid(0, int_rec_syst1); 00547 00548 //Scale the input data if necessary: 00549 if (Lc != 1.0) { 00550 rec_syst1 *= Lc; 00551 rec_syst2 *= Lc; 00552 rec_parity1 *= Lc; 00553 rec_parity2 *= Lc; 00554 } 00555 00556 //Decode the block: 00557 CONTINUE = true; 00558 nrof_used_iterations_i = iterations; 00559 for (j = 0; j < iterations; j++) { 00560 00561 rscc1.log_decode_n2(rec_syst1, rec_parity1, Le21, Le12, true, metric); 00562 if (logmax_scale_factor != 1.0) { Le12 *= logmax_scale_factor; } 00563 float_interleaver.interleave(Le12, Le12_int); 00564 00565 rscc2.log_decode_n2(rec_syst2, rec_parity2, Le12_int, Le21_int, true, metric); 00566 if (logmax_scale_factor != 1.0) { Le21_int *= logmax_scale_factor; } 00567 float_interleaver.deinterleave(Le21_int, Le21); 00568 00569 if (adaptive_stop) { 00570 L = rec_syst1.left(Nuncoded) + Le21.left(Nuncoded) + Le12.left(Nuncoded); 00571 for (l = 0; l < Nuncoded; l++) {(L(l) > 0.0) ? (temp_decoded_bits(l) = bin(0)) : (temp_decoded_bits(l) = bin(1)); } 00572 if (j == 0) { decoded_bits_previous_iteration = temp_decoded_bits; } 00573 else { 00574 if (temp_decoded_bits == decoded_bits_previous_iteration) { 00575 CONTINUE = false; 00576 } 00577 else if (j < (iterations - 1)) { 00578 decoded_bits_previous_iteration = temp_decoded_bits; 00579 } 00580 } 00581 } 00582 00583 if (CHECK_TRUE_BITS) { 00584 L = rec_syst1.left(Nuncoded) + Le21.left(Nuncoded) + Le12.left(Nuncoded); 00585 for (l = 0; l < Nuncoded; l++) {(L(l) > 0.0) ? (temp_decoded_bits(l) = bin(0)) : (temp_decoded_bits(l) = bin(1)); } 00586 if (temp_decoded_bits == true_bits.mid(i*Nuncoded, Nuncoded)) { 00587 CONTINUE = false; 00588 } 00589 } 00590 00591 if (CONTINUE == false) { nrof_used_iterations_i = j + 1; break; } 00592 00593 } 00594 00595 //Take final bit decisions 00596 L = rec_syst1.left(Nuncoded) + Le21.left(Nuncoded) + Le12.left(Nuncoded); 00597 for (l = 0; l < Nuncoded; l++) { 00598 (L(l) > 0.0) ? (decoded_bits(count_out) = bin(0)) : (decoded_bits(count_out) = bin(1)); 00599 count_out++; 00600 } 00601 00602 nrof_used_iterations(i) = nrof_used_iterations_i; 00603 00604 } 00605 00606 } 00607 00608 ivec wcdma_turbo_interleaver_sequence(int interleaver_size) 00609 { 00610 const int MAX_INTERLEAVER_SIZE = 5114; 00611 const int MIN_INTERLEAVER_SIZE = 40; 00612 int K; //Interleaver size 00613 int R; //Number of rows of rectangular matrix 00614 int C; //Number of columns of rectangular matrix 00615 int p; //Prime number 00616 int v; //Primitive root 00617 ivec s; //Base sequence for intra-row permutation 00618 ivec q; //Minimum prime integers 00619 ivec r; //Permuted prime integers 00620 ivec T; //Inter-row permutation pattern 00621 imat U; //Intra-row permutation patter 00622 ivec I; //The interleaver sequence 00623 ivec primes, roots, Pat1, Pat2, Pat3, Pat4, Isort; 00624 int i, j, qj, temp, row, col, index, count; 00625 00626 if (interleaver_size > MAX_INTERLEAVER_SIZE) { 00627 00628 I = sort_index(randu(interleaver_size)); 00629 return I; 00630 00631 } 00632 else { 00633 00634 p = 0; 00635 v = 0; 00636 00637 //Check the range of the interleaver size: 00638 it_assert(interleaver_size <= MAX_INTERLEAVER_SIZE, "wcdma_turbo_interleaver_sequence: The interleaver size is to large"); 00639 it_assert(interleaver_size >= MIN_INTERLEAVER_SIZE, "wcdma_turbo_interleaver_sequence: The interleaver size is to small"); 00640 00641 K = interleaver_size; 00642 00643 //Definitions of primes and associated primitive roots: 00644 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"; 00645 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"; 00646 00647 //Determine R 00648 if ((K >= 40) && (K <= 159)) { 00649 R = 5; 00650 } 00651 else if (((K >= 160) && (K <= 200)) || ((K >= 481) && (K <= 530))) { 00652 R = 10; 00653 } 00654 else { 00655 R = 20; 00656 } 00657 00658 //Determine C 00659 if ((K >= 481) && (K <= 530)) { 00660 p = 53; 00661 v = 2; 00662 C = p; 00663 } 00664 else { 00665 //Find minimum prime p such that (p+1) - K/R >= 0 ... 00666 for (i = 0; i < primes.length(); i++) { 00667 if ((double(primes(i) + 1) - double(K) / double(R)) >= 0.0) { 00668 p = primes(i); 00669 v = roots(i); 00670 break; 00671 } 00672 } 00673 //... and etermine C such that 00674 if ((double(p) - double(K) / double(R)) >= 0.0) { 00675 if ((double(p) - 1.0 - double(K) / double(R)) >= 0.0) { 00676 C = p - 1; 00677 } 00678 else { 00679 C = p; 00680 } 00681 } 00682 else { 00683 C = p + 1; 00684 } 00685 } 00686 00687 //Construct the base sequencs s for intra-row permutaions 00688 s.set_size(p - 1, false); 00689 s.clear(); 00690 s(0) = 1; 00691 for (i = 1; i <= (p - 2); i++) { 00692 s(i) = mod(v * s(i - 1), p); 00693 } 00694 00695 //Let q(0) = 1 be the first prime integer in {q(j)}, and select the consecutive 00696 //minimum prime integers {q(j)}, j = 1, 2, ..., (R-1) such that gcd( q(j), p-1) == 1, q(j) > 6, and q(j) > q(j-1) 00697 q.set_size(R, false); 00698 q.clear(); 00699 q(0) = 1; 00700 for (j = 1; j <= (R - 1); j++) { 00701 for (i = 0; i < primes.length(); i++) { 00702 qj = primes(i); 00703 if ((qj > 6) && (qj > q(j - 1))) { 00704 if (gcd(qj, p - 1) == 1) { 00705 q(j) = qj; 00706 break; 00707 } 00708 } 00709 } 00710 } 00711 00712 //Definitions of Pat1, Pat2, Pat3, and Pat4: 00713 Pat1 = "19 9 14 4 0 2 5 7 12 18 10 8 13 17 3 1 16 6 15 11"; 00714 Pat2 = "19 9 14 4 0 2 5 7 12 18 16 13 17 15 3 1 6 11 8 10"; 00715 Pat3 = "9 8 7 6 5 4 3 2 1 0"; 00716 Pat4 = "4 3 2 1 0"; 00717 00718 //T(j) is the inter-row permutation patters defined as one of the following four 00719 //kinds of patterns: Pat1, Pat2, Pat3, and Pat4 depending on the number of input bits K 00720 if (K >= 3211) { 00721 T = Pat1; 00722 } 00723 else if (K >= 3161) { 00724 T = Pat2; 00725 } 00726 else if (K >= 2481) { 00727 T = Pat1; 00728 } 00729 else if (K >= 2281) { 00730 T = Pat2; 00731 } 00732 else if (K >= 531) { 00733 T = Pat1; 00734 } 00735 else if (K >= 481) { 00736 T = Pat3; 00737 } 00738 else if (K >= 201) { 00739 T = Pat1; 00740 } 00741 else if (K >= 160) { 00742 T = Pat3; 00743 } 00744 else { 00745 T = Pat4; 00746 } 00747 00748 //Permute {q(j)} to make {r(j)} such that r(T(j)) = q(j), j = 0, 1, ..., (R-1), 00749 //where T(j) indicates the original row position of the j-th permuted row 00750 r.set_size(R, false); 00751 r.clear(); 00752 for (j = 0; j <= (R - 1); j++) { 00753 r(T(j)) = q(j); 00754 } 00755 00756 //U(j,i) is the input bit position of i-th output after the permutation of j-th row 00757 //Perform the j-th (j=0, 1, 2, ..., (R-1)) intra-row permutation as 00758 U.set_size(R, C, false); 00759 U.clear(); 00760 if (C == p) { 00761 for (j = 0; j <= (R - 1); j++) { 00762 for (i = 0; i <= (p - 2); i++) { 00763 U(j, i) = s(mod(i * r(j), p - 1)); 00764 } 00765 U(j, p - 1) = 0; 00766 } 00767 } 00768 else if (C == (p + 1)) { 00769 for (j = 0; j <= (R - 1); j++) { 00770 for (i = 0; i <= (p - 2); i++) { 00771 U(j, i) = s(mod(i * r(j), p - 1)); 00772 } 00773 U(j, p - 1) = 0; 00774 U(j, p) = p; 00775 } 00776 if (K == (C*R)) { 00777 temp = U(R - 1, p); 00778 U(R - 1, p) = U(R - 1, 0); 00779 U(R - 1, 0) = temp; 00780 } 00781 } 00782 else if (C == (p - 1)) { 00783 for (j = 0; j <= (R - 1); j++) { 00784 for (i = 0; i <= (p - 2); i++) { 00785 U(j, i) = s(mod(i * r(j), p - 1)) - 1; 00786 } 00787 } 00788 } 00789 00790 //Calculate the interleaver sequence: 00791 I.set_size(K, false); 00792 I.clear(); 00793 count = 0; 00794 for (i = 0; i < C; i++) { 00795 for (j = 0; j < R; j++) { 00796 row = T(j); 00797 col = U(row, i); 00798 index = row * C + col; 00799 if (index < K) { 00800 I(count) = index; 00801 count++; 00802 } 00803 } 00804 } 00805 00806 return I; 00807 } 00808 } 00809 00810 } // namespace itpp
Generated on Fri Aug 14 15:28:22 2009 for IT++ by Doxygen 1.5.9