00001 00030 #ifndef INTERLEAVE_H 00031 #define INTERLEAVE_H 00032 00033 #ifndef _MSC_VER 00034 # include <itpp/config.h> 00035 #else 00036 # include <itpp/config_msvc.h> 00037 #endif 00038 00039 #include <itpp/base/vec.h> 00040 #include <itpp/base/mat.h> 00041 #include <itpp/base/random.h> 00042 #include <itpp/base/sort.h> 00043 00044 00045 namespace itpp 00046 { 00047 00067 template <class T> 00068 class Block_Interleaver 00069 { 00070 public: 00072 Block_Interleaver(void) {rows = 0; cols = 0;}; 00074 Block_Interleaver(int in_rows, int in_cols); 00076 Vec<T> interleave(const Vec<T> &input); 00078 void interleave(const Vec<T> &input, Vec<T> &output); 00080 Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0); 00082 void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0); 00084 void set_rows(int in_rows) {rows = in_rows;}; 00086 void set_cols(int in_cols) {cols = in_cols;}; 00088 int get_rows(void) {return rows;}; 00090 int get_cols(void) {return cols;}; 00091 private: 00092 int rows, cols, input_length; 00093 }; 00094 00114 template <class T> 00115 class Cross_Interleaver 00116 { 00117 public: 00119 Cross_Interleaver(void) {order = 0;}; 00121 Cross_Interleaver(int in_order); 00123 Vec<T> interleave(const Vec<T> &input); 00125 void interleave(const Vec<T> &input, Vec<T> &output); 00127 Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0); 00129 void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0); 00131 void set_order(int in_order); 00133 int get_order(void) {return order;}; 00134 private: 00135 int order; 00136 int input_length; 00137 Mat<T> inter_matrix; 00138 Vec<T> tempvec, zerostemp; 00139 }; 00140 00157 template <class T> 00158 class Sequence_Interleaver 00159 { 00160 public: 00162 Sequence_Interleaver(void) {interleaver_depth = 0;}; 00168 Sequence_Interleaver(int in_interleaver_depth); 00174 Sequence_Interleaver(ivec in_interleaver_sequence); 00176 Vec<T> interleave(const Vec<T> &input); 00178 void interleave(const Vec<T> &input, Vec<T> &output); 00180 Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0); 00182 void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0); 00184 void randomize_interleaver_sequence(); 00186 ivec get_interleaver_sequence(); 00188 void set_interleaver_sequence(ivec in_interleaver_sequence); 00190 void set_interleaver_depth(int in_interleaver_depth) { interleaver_depth = in_interleaver_depth; }; 00192 int get_interleaver_depth(void) { return interleaver_depth; }; 00193 private: 00194 ivec interleaver_sequence; 00195 int interleaver_depth, input_length; 00196 }; 00197 00198 //----------------------------------------------------------------------------- 00199 // Implementation of templated members starts here 00200 //----------------------------------------------------------------------------- 00201 00202 //-------------------------- Block Interleaver --------------------------------- 00203 00204 template<class T> 00205 Block_Interleaver<T>::Block_Interleaver(int in_rows, int in_cols) 00206 { 00207 rows = in_rows; 00208 cols = in_cols; 00209 input_length = 0; 00210 } 00211 00212 template<class T> 00213 void Block_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output) 00214 { 00215 input_length = input.length(); 00216 int steps = (int)std::ceil(double(input_length) / double(rows * cols)); 00217 int output_length = steps * rows * cols; 00218 output.set_length(output_length, false); 00219 int s, r, c; 00220 00221 if (input_length == output_length) { 00222 //Block interleaver loop: All steps. 00223 for (s = 0; s < steps; s++) { 00224 for (c = 0; c < cols; c++) { 00225 for (r = 0; r < rows; r++) { 00226 output(s*rows*cols + r*cols + c) = input(s * rows * cols + c * rows + r); 00227 } 00228 } 00229 } 00230 } 00231 else { 00232 //Block interleaver loop: All, but the last, steps. 00233 for (s = 0; s < steps - 1; s++) { 00234 for (c = 0; c < cols; c++) { 00235 for (r = 0; r < rows; r++) { 00236 output(s*rows*cols + r*cols + c) = input(s * rows * cols + c * rows + r); 00237 } 00238 } 00239 } 00240 //The last step. 00241 Vec<T> zerovect(output_length - input_length); 00242 zerovect.clear(); 00243 Vec<T> temp_last_input = concat(input.right(rows * cols - zerovect.length()), zerovect); 00244 for (c = 0; c < cols; c++) { 00245 for (r = 0; r < rows; r++) { 00246 output((steps - 1)*rows*cols + r*cols + c) = temp_last_input(c * rows + r); 00247 } 00248 } 00249 } 00250 } 00251 00252 template<class T> 00253 Vec<T> Block_Interleaver<T>::interleave(const Vec<T> &input) 00254 { 00255 Vec<T> output; 00256 interleave(input, output); 00257 return output; 00258 } 00259 00260 template<class T> 00261 void Block_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros) 00262 { 00263 int thisinput_length = input.length(); 00264 int steps = (int)std::ceil(double(thisinput_length) / double(rows * cols)); 00265 int output_length = steps * rows * cols; 00266 output.set_size(output_length, false); 00267 int s, r, c; 00268 00269 if (thisinput_length == output_length) { 00270 //Block deinterleaver loop: All, but the last, steps. 00271 for (s = 0; s < steps; s++) { 00272 for (r = 0; r < rows; r++) { 00273 for (c = 0; c < cols; c++) { 00274 output(s*rows*cols + c*rows + r) = input(s * rows * cols + r * cols + c); 00275 } 00276 } 00277 } 00278 } 00279 else { 00280 //Block deinterleaver loop: All, but the last, steps. 00281 for (s = 0; s < steps - 1; s++) { 00282 for (r = 0; r < rows; r++) { 00283 for (c = 0; c < cols; c++) { 00284 output(s*rows*cols + c*rows + r) = input(s * rows * cols + r * cols + c); 00285 } 00286 } 00287 } 00288 //The last step. 00289 Vec<T> zerovect(output_length - thisinput_length); 00290 zerovect.clear(); 00291 Vec<T> temp_last_input = concat(input.right(rows * cols - zerovect.length()), zerovect); 00292 for (r = 0; r < rows; r++) { 00293 for (c = 0; c < cols; c++) { 00294 output((steps - 1)*rows*cols + c*rows + r) = temp_last_input(r * cols + c); 00295 } 00296 } 00297 } 00298 if (keepzeros == 0) 00299 output.set_size(input_length, true); 00300 } 00301 00302 template<class T> 00303 Vec<T> Block_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros) 00304 { 00305 Vec<T> output; 00306 deinterleave(input, output, keepzeros); 00307 return output; 00308 } 00309 00310 //---------------------------- Cross Interleaver --------------------------- 00311 00312 template<class T> 00313 Cross_Interleaver<T>::Cross_Interleaver(int in_order) 00314 { 00315 order = in_order; 00316 input_length = 0; 00317 inter_matrix.set_size(order, order, false); 00318 tempvec.set_size(order, false); 00319 zerostemp.set_size(order, false); 00320 } 00321 00322 template<class T> 00323 void Cross_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output) 00324 { 00325 input_length = input.length(); 00326 int steps = (int)std::ceil(float(input_length) / order) + order; 00327 int output_length = steps * order; 00328 output.set_length(output_length, false); 00329 int i, r, c; 00330 00331 inter_matrix.clear(); 00332 zerostemp.clear(); 00333 00334 //Cross interleaver loop: 00335 for (i = 0; i < steps; i++) { 00336 00337 //Shift the matrix to the right: 00338 for (c = order - 1; c > 0; c--) 00339 inter_matrix.set_col(c, inter_matrix.get_col(c - 1)); 00340 00341 // Write the new data to the matrix 00342 if ((i*order + order) < input_length) 00343 tempvec = input.mid(i * order, order); 00344 else if ((i*order) < input_length) 00345 tempvec = concat(input.right(input_length - i * order), zerostemp.left(order - (input_length - i * order))); 00346 else 00347 tempvec.clear(); 00348 inter_matrix.set_col(0, tempvec); 00349 00350 //Read the matrix diagonal-wise: 00351 for (r = 0; r < order; r++) 00352 output(i*order + r) = inter_matrix(r, r); 00353 } 00354 } 00355 00356 template<class T> 00357 Vec<T> Cross_Interleaver<T>::interleave(const Vec<T> &input) 00358 { 00359 Vec<T> output; 00360 interleave(input, output); 00361 return output; 00362 } 00363 00364 template<class T> 00365 void Cross_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros) 00366 { 00367 int thisinput_length = input.length(); 00368 int steps = (int)std::ceil(float(thisinput_length) / order) + order; 00369 int output_length = steps * order; 00370 output.set_size(output_length, false); 00371 int i, r, c; 00372 00373 inter_matrix.clear(); 00374 zerostemp.clear(); 00375 00376 //Cross interleaver loop: 00377 for (i = 0; i < steps; i++) { 00378 00379 //Shift the matrix to the right: 00380 for (c = order - 1; c > 0; c--) 00381 inter_matrix.set_col(c, inter_matrix.get_col(c - 1)); 00382 00383 // Write the new data to the matrix 00384 if ((i*order + order) < thisinput_length) 00385 tempvec = input.mid(i * order, order); 00386 else if ((i*order) < thisinput_length) 00387 tempvec = concat(input.right(thisinput_length - i * order), zerostemp.left(order - (thisinput_length - i * order))); 00388 else 00389 tempvec.clear(); 00390 inter_matrix.set_col(0, tempvec); 00391 00392 //Read the matrix diagonal-wise: 00393 for (r = 0; r < order; r++) 00394 output(i*order + r) = inter_matrix(r, order - 1 - r); 00395 } 00396 if (keepzeros == 0) 00397 output = output.mid(round_i(std::pow(double(order), 2)) - order, input_length); 00398 } 00399 00400 template<class T> 00401 Vec<T> Cross_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros) 00402 { 00403 Vec<T> output; 00404 deinterleave(input, output, keepzeros); 00405 return output; 00406 } 00407 00408 template<class T> 00409 void Cross_Interleaver<T>::set_order(int in_order) 00410 { 00411 order = in_order; 00412 input_length = 0; 00413 inter_matrix.set_size(order, order, false); 00414 tempvec.set_size(order, false); 00415 zerostemp.set_size(order, false); 00416 } 00417 00418 //------------------- Sequence Interleaver -------------------------------- 00419 00420 template<class T> 00421 Sequence_Interleaver<T>::Sequence_Interleaver(int in_interleaver_depth) 00422 { 00423 interleaver_depth = in_interleaver_depth; 00424 interleaver_sequence = sort_index(randu(in_interleaver_depth)); 00425 input_length = 0; 00426 } 00427 00428 template<class T> 00429 Sequence_Interleaver<T>::Sequence_Interleaver(ivec in_interleaver_sequence) 00430 { 00431 interleaver_depth = in_interleaver_sequence.length(); 00432 interleaver_sequence = in_interleaver_sequence; 00433 input_length = 0; 00434 } 00435 00436 template<class T> 00437 void Sequence_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output) 00438 { 00439 input_length = input.length(); 00440 int steps = (int)std::ceil(double(input_length) / double(interleaver_depth)); 00441 int output_length = steps * interleaver_depth; 00442 output.set_size(output_length, false); 00443 int s, i; 00444 00445 if (input_length == output_length) { 00446 00447 //Sequence interleaver loop: All steps. 00448 for (s = 0; s < steps; s++) { 00449 for (i = 0; i < interleaver_depth; i++) { 00450 output(s*interleaver_depth + i) = input(s * interleaver_depth + interleaver_sequence(i)); 00451 } 00452 } 00453 00454 } 00455 else { 00456 00457 //Sequence interleaver loop: All, but the last, steps. 00458 for (s = 0; s < steps - 1; s++) { 00459 for (i = 0; i < interleaver_depth; i++) { 00460 output(s*interleaver_depth + i) = input(s * interleaver_depth + interleaver_sequence(i)); 00461 } 00462 } 00463 //The last step. 00464 Vec<T> zerovect(output_length - input_length); 00465 zerovect.clear(); 00466 Vec<T> temp_last_input = concat(input.right(interleaver_depth - zerovect.length()), zerovect); 00467 for (i = 0; i < interleaver_depth; i++) { 00468 output((steps - 1)*interleaver_depth + i) = temp_last_input(interleaver_sequence(i)); 00469 } 00470 00471 } 00472 } 00473 00474 template<class T> 00475 Vec<T> Sequence_Interleaver<T>::interleave(const Vec<T> &input) 00476 { 00477 Vec<T> output; 00478 interleave(input, output); 00479 return output; 00480 } 00481 00482 template<class T> 00483 void Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros) 00484 { 00485 int thisinput_length = input.length(); 00486 int steps = (int)std::ceil(double(thisinput_length) / double(interleaver_depth)); 00487 int output_length = steps * interleaver_depth; 00488 output.set_length(output_length, false); 00489 int s, i; 00490 00491 if (thisinput_length == output_length) { 00492 00493 //Sequence interleaver loop: All steps. 00494 for (s = 0; s < steps; s++) { 00495 for (i = 0; i < interleaver_depth; i++) { 00496 output(s*interleaver_depth + interleaver_sequence(i)) = input(s * interleaver_depth + i); 00497 } 00498 } 00499 00500 } 00501 else { 00502 //Sequence interleaver loop: All, but the last, steps. 00503 for (s = 0; s < steps - 1; s++) { 00504 for (i = 0; i < interleaver_depth; i++) { 00505 output(s*interleaver_depth + interleaver_sequence(i)) = input(s * interleaver_depth + i); 00506 } 00507 } 00508 //The last step. 00509 Vec<T> zerovect(output_length - thisinput_length); 00510 zerovect.clear(); 00511 Vec<T> temp_last_input = concat(input.right(interleaver_depth - zerovect.length()), zerovect); 00512 for (i = 0; i < interleaver_depth; i++) { 00513 output((steps - 1)*interleaver_depth + interleaver_sequence(i)) = temp_last_input(i); 00514 } 00515 if (keepzeros == 0) 00516 output.set_size(input_length, true); 00517 } 00518 00519 } 00520 00521 template<class T> 00522 Vec<T> Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros) 00523 { 00524 Vec<T> output; 00525 deinterleave(input, output, keepzeros); 00526 return output; 00527 } 00528 00529 template<class T> 00530 void Sequence_Interleaver<T>::randomize_interleaver_sequence() 00531 { 00532 interleaver_sequence = sort_index(randu(interleaver_depth)); 00533 } 00534 00535 template<class T> 00536 ivec Sequence_Interleaver<T>::get_interleaver_sequence() 00537 { 00538 return interleaver_sequence; 00539 } 00540 00541 template<class T> 00542 void Sequence_Interleaver<T>::set_interleaver_sequence(ivec in_interleaver_sequence) 00543 { 00544 interleaver_sequence = in_interleaver_sequence; 00545 interleaver_depth = interleaver_sequence.size(); 00546 } 00547 00549 00550 // ---------------------------------------------------------------------- 00551 // Instantiations 00552 // ---------------------------------------------------------------------- 00553 00554 #ifdef HAVE_EXTERN_TEMPLATE 00555 00556 extern template class Block_Interleaver<double>; 00557 extern template class Block_Interleaver<short>; 00558 extern template class Block_Interleaver<int>; 00559 extern template class Block_Interleaver<std::complex<double> >; 00560 extern template class Block_Interleaver<bin>; 00561 00562 extern template class Cross_Interleaver<double>; 00563 extern template class Cross_Interleaver<short>; 00564 extern template class Cross_Interleaver<int>; 00565 extern template class Cross_Interleaver<std::complex<double> >; 00566 extern template class Cross_Interleaver<bin>; 00567 00568 extern template class Sequence_Interleaver<double>; 00569 extern template class Sequence_Interleaver<short>; 00570 extern template class Sequence_Interleaver<int>; 00571 extern template class Sequence_Interleaver<std::complex<double> >; 00572 extern template class Sequence_Interleaver<bin>; 00573 00574 #endif // HAVE_EXTERN_TEMPLATE 00575 00577 00578 } // namespace itpp 00579 00580 #endif // #ifndef INTERLEAVE_H
Generated on Tue Nov 23 08:45:11 2010 for IT++ by Doxygen 1.6.1