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