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