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