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 00066 template <class T> 00067 class Block_Interleaver { 00068 public: 00070 Block_Interleaver(void) {rows = 0; cols = 0;}; 00072 Block_Interleaver(int in_rows, int in_cols); 00074 Vec<T> interleave(const Vec<T> &input); 00076 void interleave(const Vec<T> &input, Vec<T> &output); 00078 Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0 ); 00080 void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0 ); 00082 void set_rows(int in_rows) {rows = in_rows;}; 00084 void set_cols(int in_cols) {cols = in_cols;}; 00086 int get_rows(void) {return rows;}; 00088 int get_cols(void) {return cols;}; 00089 private: 00090 int rows, cols, input_length; 00091 }; 00092 00112 template <class T> 00113 class Cross_Interleaver { 00114 public: 00116 Cross_Interleaver(void) {order = 0;}; 00118 Cross_Interleaver(int in_order); 00120 Vec<T> interleave(const Vec<T> &input); 00122 void interleave(const Vec<T> &input, Vec<T> &output); 00124 Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0); 00126 void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0); 00128 void set_order(int in_order); 00130 int get_order(void) {return order;}; 00131 private: 00132 int order; 00133 int input_length; 00134 Mat<T> inter_matrix; 00135 Vec<T> tempvec, zerostemp; 00136 }; 00137 00154 template <class T> 00155 class Sequence_Interleaver { 00156 public: 00158 Sequence_Interleaver(void) {interleaver_depth = 0;}; 00164 Sequence_Interleaver(int in_interleaver_depth); 00170 Sequence_Interleaver(ivec in_interleaver_sequence); 00172 Vec<T> interleave(const Vec<T> &input); 00174 void interleave(const Vec<T> &input, Vec<T> &output); 00176 Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0 ); 00178 void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0 ); 00180 void randomize_interleaver_sequence(); 00182 ivec get_interleaver_sequence(); 00184 void set_interleaver_sequence(ivec in_interleaver_sequence); 00186 void set_interleaver_depth(int in_interleaver_depth) { interleaver_depth = in_interleaver_depth; }; 00188 int get_interleaver_depth(void) { return interleaver_depth; }; 00189 private: 00190 ivec interleaver_sequence; 00191 int interleaver_depth, input_length; 00192 }; 00193 00194 //----------------------------------------------------------------------------- 00195 // Implementation of templated members starts here 00196 //----------------------------------------------------------------------------- 00197 00198 //-------------------------- Block Interleaver --------------------------------- 00199 00200 template<class T> 00201 Block_Interleaver<T>::Block_Interleaver(int in_rows, int in_cols) 00202 { 00203 rows = in_rows; 00204 cols = in_cols; 00205 input_length = 0; 00206 } 00207 00208 template<class T> 00209 void Block_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output) 00210 { 00211 input_length = input.length(); 00212 int steps = (int)std::ceil( double(input_length)/double(rows*cols) ); 00213 int output_length = steps * rows * cols; 00214 output.set_length(output_length,false); 00215 int s, r, c; 00216 00217 if (input_length==output_length) { 00218 //Block interleaver loop: All steps. 00219 for (s=0; s<steps; s++) { 00220 for (c=0; c<cols; c++) { 00221 for (r=0; r<rows; r++) { 00222 output(s*rows*cols+r*cols+c) = input(s*rows*cols+c*rows+r); 00223 } 00224 } 00225 } 00226 } else { 00227 //Block interleaver loop: All, but the last, steps. 00228 for (s=0; s<steps-1; s++) { 00229 for (c=0; c<cols; c++) { 00230 for (r=0; r<rows; r++) { 00231 output(s*rows*cols+r*cols+c) = input(s*rows*cols+c*rows+r); 00232 } 00233 } 00234 } 00235 //The last step. 00236 Vec<T> zerovect(output_length - input_length); 00237 zerovect.clear(); 00238 Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect ); 00239 for (c=0; c<cols; c++) { 00240 for (r=0; r<rows; r++) { 00241 output((steps-1)*rows*cols+r*cols+c) = temp_last_input(c*rows+r); 00242 } 00243 } 00244 } 00245 } 00246 00247 template<class T> 00248 Vec<T> Block_Interleaver<T>::interleave(const Vec<T> &input) 00249 { 00250 Vec<T> output; 00251 interleave(input,output); 00252 return output; 00253 } 00254 00255 template<class T> 00256 void Block_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros) 00257 { 00258 int thisinput_length = input.length(); 00259 int steps = (int)std::ceil( double(thisinput_length)/double(rows*cols) ); 00260 int output_length = steps * rows * cols; 00261 output.set_size(output_length,false); 00262 int s, r, c; 00263 00264 if (thisinput_length==output_length) { 00265 //Block deinterleaver loop: All, but the last, steps. 00266 for (s=0; s<steps; s++) { 00267 for (r=0; r<rows; r++) { 00268 for (c=0; c<cols; c++) { 00269 output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c); 00270 } 00271 } 00272 } 00273 } else { 00274 //Block deinterleaver loop: All, but the last, steps. 00275 for (s=0; s<steps-1; s++) { 00276 for (r=0; r<rows; r++) { 00277 for (c=0; c<cols; c++) { 00278 output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c); 00279 } 00280 } 00281 } 00282 //The last step. 00283 Vec<T> zerovect(output_length - thisinput_length); 00284 zerovect.clear(); 00285 Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect ); 00286 for (r=0; r<rows; r++) { 00287 for (c=0; c<cols; c++) { 00288 output((steps-1)*rows*cols+c*rows+r) = temp_last_input(r*cols+c); 00289 } 00290 } 00291 } 00292 if (keepzeros == 0) 00293 output.set_size(input_length,true); 00294 } 00295 00296 template<class T> 00297 Vec<T> Block_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros) 00298 { 00299 Vec<T> output; 00300 deinterleave(input,output,keepzeros); 00301 return output; 00302 } 00303 00304 //---------------------------- Cross Interleaver --------------------------- 00305 00306 template<class T> 00307 Cross_Interleaver<T>::Cross_Interleaver(int in_order) 00308 { 00309 order = in_order; 00310 input_length = 0; 00311 inter_matrix.set_size(order,order,false); 00312 tempvec.set_size(order,false); 00313 zerostemp.set_size(order,false); 00314 } 00315 00316 template<class T> 00317 void Cross_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output) 00318 { 00319 input_length = input.length(); 00320 int steps = (int)std::ceil( float(input_length) / order ) + order; 00321 int output_length = steps * order; 00322 output.set_length(output_length,false); 00323 int i, r, c; 00324 00325 inter_matrix.clear(); 00326 zerostemp.clear(); 00327 00328 //Cross interleaver loop: 00329 for (i=0; i< steps; i++ ){ 00330 00331 //Shift the matrix to the right: 00332 for (c=order-1; c>0; c--) 00333 inter_matrix.set_col(c, inter_matrix.get_col(c-1) ); 00334 00335 // Write the new data to the matrix 00336 if ((i*order+order)<input_length) 00337 tempvec = input.mid(i*order,order); 00338 else if ((i*order)<input_length) 00339 tempvec = concat( input.right(input_length-i*order), zerostemp.left(order-(input_length-i*order)) ); 00340 else 00341 tempvec.clear(); 00342 inter_matrix.set_col(0,tempvec); 00343 00344 //Read the matrix diagonal-wise: 00345 for (r=0; r<order; r++) 00346 output(i*order+r) = inter_matrix(r,r); 00347 } 00348 } 00349 00350 template<class T> 00351 Vec<T> Cross_Interleaver<T>::interleave(const Vec<T> &input) 00352 { 00353 Vec<T> output; 00354 interleave(input,output); 00355 return output; 00356 } 00357 00358 template<class T> 00359 void Cross_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros) 00360 { 00361 int thisinput_length = input.length(); 00362 int steps = (int)std::ceil( float(thisinput_length) / order ) + order; 00363 int output_length = steps * order; 00364 output.set_size(output_length,false); 00365 int i, r, c; 00366 00367 inter_matrix.clear(); 00368 zerostemp.clear(); 00369 00370 //Cross interleaver loop: 00371 for (i=0; i<steps; i++ ){ 00372 00373 //Shift the matrix to the right: 00374 for (c=order-1; c>0; c--) 00375 inter_matrix.set_col(c,inter_matrix.get_col(c-1)); 00376 00377 // Write the new data to the matrix 00378 if ((i*order+order)<thisinput_length) 00379 tempvec = input.mid(i*order,order); 00380 else if ((i*order)<thisinput_length) 00381 tempvec = concat( input.right(thisinput_length-i*order), zerostemp.left(order-(thisinput_length-i*order)) ); 00382 else 00383 tempvec.clear(); 00384 inter_matrix.set_col(0,tempvec); 00385 00386 //Read the matrix diagonal-wise: 00387 for (r=0; r<order; r++) 00388 output(i*order+r) = inter_matrix(r,order-1-r); 00389 } 00390 if (keepzeros == 0) 00391 output = output.mid(round_i(std::pow(double(order),2))-order,input_length); 00392 } 00393 00394 template<class T> 00395 Vec<T> Cross_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros) 00396 { 00397 Vec<T> output; 00398 deinterleave(input,output,keepzeros); 00399 return output; 00400 } 00401 00402 template<class T> 00403 void Cross_Interleaver<T>::set_order(int in_order) 00404 { 00405 order = in_order; 00406 input_length = 0; 00407 inter_matrix.set_size(order,order,false); 00408 tempvec.set_size(order,false); 00409 zerostemp.set_size(order,false); 00410 } 00411 00412 //------------------- Sequence Interleaver -------------------------------- 00413 00414 template<class T> 00415 Sequence_Interleaver<T>::Sequence_Interleaver(int in_interleaver_depth) 00416 { 00417 interleaver_depth = in_interleaver_depth; 00418 interleaver_sequence = sort_index(randu(in_interleaver_depth)); 00419 input_length = 0; 00420 } 00421 00422 template<class T> 00423 Sequence_Interleaver<T>::Sequence_Interleaver(ivec in_interleaver_sequence) 00424 { 00425 interleaver_depth = in_interleaver_sequence.length(); 00426 interleaver_sequence = in_interleaver_sequence; 00427 input_length = 0; 00428 } 00429 00430 template<class T> 00431 void Sequence_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output) 00432 { 00433 input_length = input.length(); 00434 int steps = (int)std::ceil( double(input_length)/double(interleaver_depth) ); 00435 int output_length = steps*interleaver_depth; 00436 output.set_size(output_length,false); 00437 int s, i; 00438 00439 if (input_length==output_length) { 00440 00441 //Sequence interleaver loop: All steps. 00442 for (s=0; s<steps; s++) { 00443 for (i=0; i<interleaver_depth; i++) { 00444 output(s*interleaver_depth+i) = input(s*interleaver_depth+interleaver_sequence(i)); 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 } else { 00494 //Sequence interleaver loop: All, but the last, steps. 00495 for (s=0; s<steps-1; s++) { 00496 for (i=0; i<interleaver_depth; i++) { 00497 output(s*interleaver_depth+interleaver_sequence(i)) = input(s*interleaver_depth+i); 00498 } 00499 } 00500 //The last step. 00501 Vec<T> zerovect(output_length - thisinput_length); 00502 zerovect.clear(); 00503 Vec<T> temp_last_input = concat( input.right(interleaver_depth-zerovect.length()), zerovect ); 00504 for (i=0; i<interleaver_depth; i++) { 00505 output((steps-1)*interleaver_depth+interleaver_sequence(i)) = temp_last_input(i); 00506 } 00507 if (keepzeros == 0) 00508 output.set_size(input_length,true); 00509 } 00510 00511 } 00512 00513 template<class T> 00514 Vec<T> Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros) 00515 { 00516 Vec<T> output; 00517 deinterleave(input,output,keepzeros); 00518 return output; 00519 } 00520 00521 template<class T> 00522 void Sequence_Interleaver<T>::randomize_interleaver_sequence() 00523 { 00524 interleaver_sequence = sort_index(randu(interleaver_depth)); 00525 } 00526 00527 template<class T> 00528 ivec Sequence_Interleaver<T>::get_interleaver_sequence() 00529 { 00530 return interleaver_sequence; 00531 } 00532 00533 template<class T> 00534 void Sequence_Interleaver<T>::set_interleaver_sequence(ivec in_interleaver_sequence) 00535 { 00536 interleaver_sequence = in_interleaver_sequence; 00537 interleaver_depth = interleaver_sequence.size(); 00538 } 00539 00541 00542 // ---------------------------------------------------------------------- 00543 // Instantiations 00544 // ---------------------------------------------------------------------- 00545 00546 #ifdef HAVE_EXTERN_TEMPLATE 00547 00548 extern template class Block_Interleaver<double>; 00549 extern template class Block_Interleaver<short>; 00550 extern template class Block_Interleaver<int>; 00551 extern template class Block_Interleaver<std::complex<double> >; 00552 extern template class Block_Interleaver<bin>; 00553 00554 extern template class Cross_Interleaver<double>; 00555 extern template class Cross_Interleaver<short>; 00556 extern template class Cross_Interleaver<int>; 00557 extern template class Cross_Interleaver<std::complex<double> >; 00558 extern template class Cross_Interleaver<bin>; 00559 00560 extern template class Sequence_Interleaver<double>; 00561 extern template class Sequence_Interleaver<short>; 00562 extern template class Sequence_Interleaver<int>; 00563 extern template class Sequence_Interleaver<std::complex<double> >; 00564 extern template class Sequence_Interleaver<bin>; 00565 00566 #endif // HAVE_EXTERN_TEMPLATE 00567 00569 00570 } // namespace itpp 00571 00572 #endif // #ifndef INTERLEAVE_H
Generated on Sun Sep 14 18:52:35 2008 for IT++ by Doxygen 1.5.6