00001 00033 #ifndef INTERLEAVE_H 00034 #define INTERLEAVE_H 00035 00036 #include <itpp/base/vec.h> 00037 #include <itpp/base/mat.h> 00038 #include <itpp/base/random.h> 00039 #include <itpp/base/sort.h> 00040 00041 00042 namespace itpp { 00043 00063 template <class T> 00064 class Block_Interleaver { 00065 public: 00067 Block_Interleaver(void) {rows = 0; cols = 0;}; 00069 Block_Interleaver(int in_rows, int in_cols); 00071 Vec<T> interleave(const Vec<T> &input); 00073 void interleave(const Vec<T> &input, Vec<T> &output); 00075 Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0 ); 00077 void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0 ); 00079 void set_rows(int in_rows) {rows = in_rows;}; 00081 void set_cols(int in_cols) {cols = in_cols;}; 00083 int get_rows(void) {return rows;}; 00085 int get_cols(void) {return cols;}; 00086 private: 00087 int rows, cols, input_length; 00088 }; 00089 00109 template <class T> 00110 class Cross_Interleaver { 00111 public: 00113 Cross_Interleaver(void) {order = 0;}; 00115 Cross_Interleaver(int in_order); 00117 Vec<T> interleave(const Vec<T> &input); 00119 void interleave(const Vec<T> &input, Vec<T> &output); 00121 Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0); 00123 void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0); 00125 void set_order(int in_order); 00127 int get_order(void) {return order;}; 00128 private: 00129 int order; 00130 int input_length; 00131 Mat<T> inter_matrix; 00132 Vec<T> tempvec, zerostemp; 00133 }; 00134 00151 template <class T> 00152 class Sequence_Interleaver { 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 } else { 00224 //Block interleaver loop: All, but the last, steps. 00225 for (s=0; s<steps-1; s++) { 00226 for (c=0; c<cols; c++) { 00227 for (r=0; r<rows; r++) { 00228 output(s*rows*cols+r*cols+c) = input(s*rows*cols+c*rows+r); 00229 } 00230 } 00231 } 00232 //The last step. 00233 Vec<T> zerovect(output_length - input_length); 00234 zerovect.clear(); 00235 Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect ); 00236 for (c=0; c<cols; c++) { 00237 for (r=0; r<rows; r++) { 00238 output((steps-1)*rows*cols+r*cols+c) = temp_last_input(c*rows+r); 00239 } 00240 } 00241 } 00242 } 00243 00244 template<class T> 00245 Vec<T> Block_Interleaver<T>::interleave(const Vec<T> &input) 00246 { 00247 Vec<T> output; 00248 interleave(input,output); 00249 return output; 00250 } 00251 00252 template<class T> 00253 void Block_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros) 00254 { 00255 int thisinput_length = input.length(); 00256 int steps = (int)std::ceil( double(thisinput_length)/double(rows*cols) ); 00257 int output_length = steps * rows * cols; 00258 output.set_size(output_length,false); 00259 int s, r, c; 00260 00261 if (thisinput_length==output_length) { 00262 //Block deinterleaver loop: All, but the last, steps. 00263 for (s=0; s<steps; s++) { 00264 for (r=0; r<rows; r++) { 00265 for (c=0; c<cols; c++) { 00266 output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c); 00267 } 00268 } 00269 } 00270 } else { 00271 //Block deinterleaver loop: All, but the last, steps. 00272 for (s=0; s<steps-1; s++) { 00273 for (r=0; r<rows; r++) { 00274 for (c=0; c<cols; c++) { 00275 output(s*rows*cols+c*rows+r) = input(s*rows*cols+r*cols+c); 00276 } 00277 } 00278 } 00279 //The last step. 00280 Vec<T> zerovect(output_length - thisinput_length); 00281 zerovect.clear(); 00282 Vec<T> temp_last_input = concat( input.right(rows*cols-zerovect.length()), zerovect ); 00283 for (r=0; r<rows; r++) { 00284 for (c=0; c<cols; c++) { 00285 output((steps-1)*rows*cols+c*rows+r) = temp_last_input(r*cols+c); 00286 } 00287 } 00288 } 00289 if (keepzeros == 0) 00290 output.set_size(input_length,true); 00291 } 00292 00293 template<class T> 00294 Vec<T> Block_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros) 00295 { 00296 Vec<T> output; 00297 deinterleave(input,output,keepzeros); 00298 return output; 00299 } 00300 00301 //---------------------------- Cross Interleaver --------------------------- 00302 00303 template<class T> 00304 Cross_Interleaver<T>::Cross_Interleaver(int in_order) 00305 { 00306 order = in_order; 00307 input_length = 0; 00308 inter_matrix.set_size(order,order,false); 00309 tempvec.set_size(order,false); 00310 zerostemp.set_size(order,false); 00311 } 00312 00313 template<class T> 00314 void Cross_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output) 00315 { 00316 input_length = input.length(); 00317 int steps = (int)std::ceil( float(input_length) / order ) + order; 00318 int output_length = steps * order; 00319 output.set_length(output_length,false); 00320 int i, r, c; 00321 00322 inter_matrix.clear(); 00323 zerostemp.clear(); 00324 00325 //Cross interleaver loop: 00326 for (i=0; i< steps; i++ ){ 00327 00328 //Shift the matrix to the right: 00329 for (c=order-1; c>0; c--) 00330 inter_matrix.set_col(c, inter_matrix.get_col(c-1) ); 00331 00332 // Write the new data to the matrix 00333 if ((i*order+order)<input_length) 00334 tempvec = input.mid(i*order,order); 00335 else if ((i*order)<input_length) 00336 tempvec = concat( input.right(input_length-i*order), zerostemp.left(order-(input_length-i*order)) ); 00337 else 00338 tempvec.clear(); 00339 inter_matrix.set_col(0,tempvec); 00340 00341 //Read the matrix diagonal-wise: 00342 for (r=0; r<order; r++) 00343 output(i*order+r) = inter_matrix(r,r); 00344 } 00345 } 00346 00347 template<class T> 00348 Vec<T> Cross_Interleaver<T>::interleave(const Vec<T> &input) 00349 { 00350 Vec<T> output; 00351 interleave(input,output); 00352 return output; 00353 } 00354 00355 template<class T> 00356 void Cross_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros) 00357 { 00358 int thisinput_length = input.length(); 00359 int steps = (int)std::ceil( float(thisinput_length) / order ) + order; 00360 int output_length = steps * order; 00361 output.set_size(output_length,false); 00362 int i, r, c; 00363 00364 inter_matrix.clear(); 00365 zerostemp.clear(); 00366 00367 //Cross interleaver loop: 00368 for (i=0; i<steps; i++ ){ 00369 00370 //Shift the matrix to the right: 00371 for (c=order-1; c>0; c--) 00372 inter_matrix.set_col(c,inter_matrix.get_col(c-1)); 00373 00374 // Write the new data to the matrix 00375 if ((i*order+order)<thisinput_length) 00376 tempvec = input.mid(i*order,order); 00377 else if ((i*order)<thisinput_length) 00378 tempvec = concat( input.right(thisinput_length-i*order), zerostemp.left(order-(thisinput_length-i*order)) ); 00379 else 00380 tempvec.clear(); 00381 inter_matrix.set_col(0,tempvec); 00382 00383 //Read the matrix diagonal-wise: 00384 for (r=0; r<order; r++) 00385 output(i*order+r) = inter_matrix(r,order-1-r); 00386 } 00387 if (keepzeros == 0) 00388 output = output.mid(round_i(std::pow(double(order),2))-order,input_length); 00389 } 00390 00391 template<class T> 00392 Vec<T> Cross_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros) 00393 { 00394 Vec<T> output; 00395 deinterleave(input,output,keepzeros); 00396 return output; 00397 } 00398 00399 template<class T> 00400 void Cross_Interleaver<T>::set_order(int in_order) 00401 { 00402 order = in_order; 00403 input_length = 0; 00404 inter_matrix.set_size(order,order,false); 00405 tempvec.set_size(order,false); 00406 zerostemp.set_size(order,false); 00407 } 00408 00409 //------------------- Sequence Interleaver -------------------------------- 00410 00411 template<class T> 00412 Sequence_Interleaver<T>::Sequence_Interleaver(int in_interleaver_depth) 00413 { 00414 interleaver_depth = in_interleaver_depth; 00415 interleaver_sequence = sort_index(randu(in_interleaver_depth)); 00416 input_length = 0; 00417 } 00418 00419 template<class T> 00420 Sequence_Interleaver<T>::Sequence_Interleaver(ivec in_interleaver_sequence) 00421 { 00422 interleaver_depth = in_interleaver_sequence.length(); 00423 interleaver_sequence = in_interleaver_sequence; 00424 input_length = 0; 00425 } 00426 00427 template<class T> 00428 void Sequence_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output) 00429 { 00430 input_length = input.length(); 00431 int steps = (int)std::ceil( double(input_length)/double(interleaver_depth) ); 00432 int output_length = steps*interleaver_depth; 00433 output.set_size(output_length,false); 00434 int s, i; 00435 00436 if (input_length==output_length) { 00437 00438 //Sequence interleaver loop: All steps. 00439 for (s=0; s<steps; s++) { 00440 for (i=0; i<interleaver_depth; i++) { 00441 output(s*interleaver_depth+i) = input(s*interleaver_depth+interleaver_sequence(i)); 00442 } 00443 } 00444 00445 } else { 00446 00447 //Sequence interleaver loop: All, but the last, steps. 00448 for (s=0; s<steps-1; 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 //The last step. 00454 Vec<T> zerovect(output_length - input_length); 00455 zerovect.clear(); 00456 Vec<T> temp_last_input = concat( input.right(interleaver_depth-zerovect.length()), zerovect ); 00457 for (i=0; i<interleaver_depth; i++) { 00458 output((steps-1)*interleaver_depth+i) = temp_last_input(interleaver_sequence(i)); 00459 } 00460 00461 } 00462 } 00463 00464 template<class T> 00465 Vec<T> Sequence_Interleaver<T>::interleave(const Vec<T> &input) 00466 { 00467 Vec<T> output; 00468 interleave(input,output); 00469 return output; 00470 } 00471 00472 template<class T> 00473 void Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros) 00474 { 00475 int thisinput_length = input.length(); 00476 int steps = (int)std::ceil( double(thisinput_length)/double(interleaver_depth) ); 00477 int output_length = steps*interleaver_depth; 00478 //long_long thisinput_length = input.length(); 00479 //long_long steps = (long_long)std::ceil( double(thisinput_length)/double(interleaver_depth) ); 00480 //long_long output_length = steps*interleaver_depth; 00481 output.set_length(output_length,false); 00482 int s, i; 00483 //long_long s, i; 00484 00485 if (thisinput_length == output_length) { 00486 00487 //Sequence interleaver loop: All steps. 00488 for (s=0; s<steps; s++) { 00489 for (i=0; i<interleaver_depth; i++) { 00490 output(s*interleaver_depth+interleaver_sequence(i)) = input(s*interleaver_depth+i); 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 00541 // ------------------------ Instantiations -------------------------------- 00542 #ifndef _MSC_VER 00543 00545 extern template class Block_Interleaver<double>; 00547 extern template class Block_Interleaver<short>; 00549 extern template class Block_Interleaver<int>; 00551 extern template class Block_Interleaver<std::complex<double> >; 00553 extern template class Block_Interleaver<bin>; 00554 00556 extern template class Cross_Interleaver<double>; 00558 extern template class Cross_Interleaver<short>; 00560 extern template class Cross_Interleaver<int>; 00562 extern template class Cross_Interleaver<std::complex<double> >; 00564 extern template class Cross_Interleaver<bin>; 00565 00567 extern template class Sequence_Interleaver<double>; 00569 extern template class Sequence_Interleaver<short>; 00571 extern template class Sequence_Interleaver<int>; 00573 extern template class Sequence_Interleaver<std::complex<double> >; 00575 extern template class Sequence_Interleaver<bin>; 00576 #endif 00577 00578 } // namespace itpp 00579 00580 #endif // #ifndef INTERLEAVE_H
Generated on Thu Apr 19 14:23:58 2007 for IT++ by Doxygen 1.4.6