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