itpp
comm
interleave.h
Go to the documentation of this file.
1
29
#ifndef INTERLEAVE_H
30
#define INTERLEAVE_H
31
32
#include <
itpp/base/vec.h
>
33
#include <
itpp/base/mat.h
>
34
#include <
itpp/base/random.h
>
35
#include <
itpp/base/sort.h
>
36
#include <itpp/itexports.h>
37
38
namespace
itpp
39
{
40
60
template
<
class
T>
61
class
Block_Interleaver
62
{
63
public
:
65
Block_Interleaver
(
void
) {rows = 0; cols = 0;};
67
Block_Interleaver
(
int
in_rows
,
int
in_cols
);
69
Vec<T>
interleave
(
const
Vec<T>
&input);
71
void
interleave
(
const
Vec<T>
&input,
Vec<T>
&output);
73
Vec<T>
deinterleave
(
const
Vec<T>
&input,
short
keepzeros
= 0);
75
void
deinterleave
(
const
Vec<T>
&input,
Vec<T>
&output,
short
keepzeros
= 0);
77
void
set_rows
(
int
in_rows
) {rows =
in_rows
;};
79
void
set_cols
(
int
in_cols
) {cols =
in_cols
;};
81
int
get_rows
(
void
) {
return
rows;};
83
int
get_cols
(
void
) {
return
cols;};
84
private
:
85
int
rows, cols, input_length;
86
};
87
107
template
<
class
T>
108
class
Cross_Interleaver
109
{
110
public
:
112
Cross_Interleaver
(
void
) {order = 0;};
114
Cross_Interleaver
(
int
in_order
);
116
Vec<T>
interleave
(
const
Vec<T>
&input);
118
void
interleave
(
const
Vec<T>
&input,
Vec<T>
&output);
120
Vec<T>
deinterleave
(
const
Vec<T>
&input,
short
keepzeros
= 0);
122
void
deinterleave
(
const
Vec<T>
&input,
Vec<T>
&output,
short
keepzeros
= 0);
124
void
set_order
(
int
in_order
);
126
int
get_order
(
void
) {
return
order;};
127
private
:
128
int
order;
129
int
input_length;
130
Mat<T>
inter_matrix;
131
Vec<T>
tempvec, zerostemp;
132
};
133
150
template
<
class
T>
151
class
Sequence_Interleaver
152
{
153
public
:
155
Sequence_Interleaver
(
void
) {interleaver_depth = 0;};
161
Sequence_Interleaver
(
int
in_interleaver_depth
);
167
Sequence_Interleaver
(ivec
in_interleaver_sequence
);
169
Vec<T>
interleave
(
const
Vec<T>
&input);
171
void
interleave
(
const
Vec<T>
&input,
Vec<T>
&output);
173
Vec<T>
deinterleave
(
const
Vec<T>
&input,
short
keepzeros
= 0);
175
void
deinterleave
(
const
Vec<T>
&input,
Vec<T>
&output,
short
keepzeros
= 0);
177
void
randomize_interleaver_sequence
();
179
ivec
get_interleaver_sequence
();
181
void
set_interleaver_sequence
(ivec
in_interleaver_sequence
);
183
void
set_interleaver_depth
(
int
in_interleaver_depth
) { interleaver_depth =
in_interleaver_depth
; };
185
int
get_interleaver_depth
(
void
) {
return
interleaver_depth; };
186
private
:
187
ivec interleaver_sequence;
188
int
interleaver_depth, input_length;
189
};
190
191
//-----------------------------------------------------------------------------
192
// Implementation of templated members starts here
193
//-----------------------------------------------------------------------------
194
195
//-------------------------- Block Interleaver ---------------------------------
196
197
template
<
class
T>
198
Block_Interleaver<T>::Block_Interleaver
(
int
in_rows
,
int
in_cols
)
199
{
200
rows =
in_rows
;
201
cols =
in_cols
;
202
input_length = 0;
203
}
204
205
template
<
class
T>
206
void
Block_Interleaver<T>::interleave
(
const
Vec<T>
&input,
Vec<T>
&output)
207
{
208
input_length = input.
length
();
209
int
steps
= (
int
)std::ceil(
double
(input_length) /
double
(rows * cols));
210
int
output_length
=
steps
* rows * cols;
211
output.
set_length
(
output_length
,
false
);
212
int
s, r,
c
;
213
214
if
(input_length ==
output_length
) {
215
//Block interleaver loop: All steps.
216
for
(s = 0; s <
steps
; s++) {
217
for
(
c
= 0;
c
< cols;
c
++) {
218
for
(r = 0; r < rows; r++) {
219
output(s*rows*cols + r*cols +
c
) = input(s * rows * cols +
c
* rows + r);
220
}
221
}
222
}
223
}
224
else
{
225
//Block interleaver loop: All, but the last, steps.
226
for
(s = 0; s <
steps
- 1; s++) {
227
for
(
c
= 0;
c
< cols;
c
++) {
228
for
(r = 0; r < rows; r++) {
229
output(s*rows*cols + r*cols +
c
) = input(s * rows * cols +
c
* rows + r);
230
}
231
}
232
}
233
//The last step.
234
Vec<T>
zerovect
(
output_length
- input_length);
235
zerovect
.clear();
236
Vec<T>
temp_last_input
=
concat
(input.
right
(rows * cols -
zerovect
.
length
()),
zerovect
);
237
for
(
c
= 0;
c
< cols;
c
++) {
238
for
(r = 0; r < rows; r++) {
239
output((
steps
- 1)*rows*cols + r*cols +
c
) =
temp_last_input
(
c
* rows + r);
240
}
241
}
242
}
243
}
244
245
template
<
class
T>
246
Vec<T>
Block_Interleaver<T>::interleave
(
const
Vec<T>
&input)
247
{
248
Vec<T>
output;
249
interleave(input, output);
250
return
output;
251
}
252
253
template
<
class
T>
254
void
Block_Interleaver<T>::deinterleave
(
const
Vec<T>
&input,
Vec<T>
&output,
short
keepzeros
)
255
{
256
int
thisinput_length
= input.
length
();
257
int
steps
= (
int
)std::ceil(
double
(
thisinput_length
) /
double
(rows * cols));
258
int
output_length
=
steps
* rows * cols;
259
output.
set_size
(
output_length
,
false
);
260
int
s, r,
c
;
261
262
if
(
thisinput_length
==
output_length
) {
263
//Block deinterleaver loop: All, but the last, steps.
264
for
(s = 0; s <
steps
; s++) {
265
for
(r = 0; r < rows; r++) {
266
for
(
c
= 0;
c
< cols;
c
++) {
267
output(s*rows*cols +
c
*rows + r) = input(s * rows * cols + r * cols +
c
);
268
}
269
}
270
}
271
}
272
else
{
273
//Block deinterleaver loop: All, but the last, steps.
274
for
(s = 0; s <
steps
- 1; s++) {
275
for
(r = 0; r < rows; r++) {
276
for
(
c
= 0;
c
< cols;
c
++) {
277
output(s*rows*cols +
c
*rows + r) = input(s * rows * cols + r * cols +
c
);
278
}
279
}
280
}
281
//The last step.
282
Vec<T>
zerovect
(
output_length
-
thisinput_length
);
283
zerovect
.clear();
284
Vec<T>
temp_last_input
=
concat
(input.
right
(rows * cols -
zerovect
.
length
()),
zerovect
);
285
for
(r = 0; r < rows; r++) {
286
for
(
c
= 0;
c
< cols;
c
++) {
287
output((
steps
- 1)*rows*cols +
c
*rows + r) =
temp_last_input
(r * cols +
c
);
288
}
289
}
290
}
291
if
(
keepzeros
== 0)
292
output.
set_size
(input_length,
true
);
293
}
294
295
template
<
class
T>
296
Vec<T>
Block_Interleaver<T>::deinterleave
(
const
Vec<T>
&input,
short
keepzeros
)
297
{
298
Vec<T>
output;
299
deinterleave(input, output,
keepzeros
);
300
return
output;
301
}
302
303
//---------------------------- Cross Interleaver ---------------------------
304
305
template
<
class
T>
306
Cross_Interleaver<T>::Cross_Interleaver
(
int
in_order
)
307
{
308
order =
in_order
;
309
input_length = 0;
310
inter_matrix.
set_size
(order, order,
false
);
311
tempvec.
set_size
(order,
false
);
312
zerostemp.
set_size
(order,
false
);
313
}
314
315
template
<
class
T>
316
void
Cross_Interleaver<T>::interleave
(
const
Vec<T>
&input,
Vec<T>
&output)
317
{
318
input_length = input.
length
();
319
int
steps
= (
int
)std::ceil(
float
(input_length) / order) + order;
320
int
output_length
=
steps
* order;
321
output.
set_length
(
output_length
,
false
);
322
int
i
, r,
c
;
323
324
inter_matrix.clear();
325
zerostemp.clear();
326
327
//Cross interleaver loop:
328
for
(
i
= 0;
i
<
steps
;
i
++) {
329
330
//Shift the matrix to the right:
331
for
(
c
= order - 1;
c
> 0;
c
--)
332
inter_matrix.set_col(
c
, inter_matrix.get_col(
c
- 1));
333
334
// Write the new data to the matrix
335
if
((
i
*order + order) < input_length)
336
tempvec = input.
mid
(
i
* order, order);
337
else
if
((
i
*order) < input_length)
338
tempvec =
concat
(input.
right
(input_length -
i
* order), zerostemp.
left
(order - (input_length -
i
* order)));
339
else
340
tempvec.clear();
341
inter_matrix.set_col(0, tempvec);
342
343
//Read the matrix diagonal-wise:
344
for
(r = 0; r < order; r++)
345
output(
i
*order + r) = inter_matrix(r, r);
346
}
347
}
348
349
template
<
class
T>
350
Vec<T>
Cross_Interleaver<T>::interleave
(
const
Vec<T>
&input)
351
{
352
Vec<T>
output;
353
interleave(input, output);
354
return
output;
355
}
356
357
template
<
class
T>
358
void
Cross_Interleaver<T>::deinterleave
(
const
Vec<T>
&input,
Vec<T>
&output,
short
keepzeros
)
359
{
360
int
thisinput_length
= input.
length
();
361
int
steps
= (
int
)std::ceil(
float
(
thisinput_length
) / order) + order;
362
int
output_length
=
steps
* order;
363
output.
set_size
(
output_length
,
false
);
364
int
i
, r,
c
;
365
366
inter_matrix.clear();
367
zerostemp.clear();
368
369
//Cross interleaver loop:
370
for
(
i
= 0;
i
<
steps
;
i
++) {
371
372
//Shift the matrix to the right:
373
for
(
c
= order - 1;
c
> 0;
c
--)
374
inter_matrix.set_col(
c
, inter_matrix.get_col(
c
- 1));
375
376
// Write the new data to the matrix
377
if
((
i
*order + order) <
thisinput_length
)
378
tempvec = input.
mid
(
i
* order, order);
379
else
if
((
i
*order) <
thisinput_length
)
380
tempvec =
concat
(input.
right
(
thisinput_length
-
i
* order), zerostemp.
left
(order - (
thisinput_length
-
i
* order)));
381
else
382
tempvec.clear();
383
inter_matrix.set_col(0, tempvec);
384
385
//Read the matrix diagonal-wise:
386
for
(r = 0; r < order; r++)
387
output(
i
*order + r) = inter_matrix(r, order - 1 - r);
388
}
389
if
(
keepzeros
== 0)
390
output = output.
mid
(
round_i
(std::pow(
double
(order), 2)) - order, input_length);
391
}
392
393
template
<
class
T>
394
Vec<T>
Cross_Interleaver<T>::deinterleave
(
const
Vec<T>
&input,
short
keepzeros
)
395
{
396
Vec<T>
output;
397
deinterleave(input, output,
keepzeros
);
398
return
output;
399
}
400
401
template
<
class
T>
402
void
Cross_Interleaver<T>::set_order
(
int
in_order
)
403
{
404
order =
in_order
;
405
input_length = 0;
406
inter_matrix.
set_size
(order, order,
false
);
407
tempvec.
set_size
(order,
false
);
408
zerostemp.
set_size
(order,
false
);
409
}
410
411
//------------------- Sequence Interleaver --------------------------------
412
413
template
<
class
T>
414
Sequence_Interleaver<T>::Sequence_Interleaver
(
int
in_interleaver_depth
)
415
{
416
interleaver_depth =
in_interleaver_depth
;
417
interleaver_sequence = sort_index(
randu
(
in_interleaver_depth
));
418
input_length = 0;
419
}
420
421
template
<
class
T>
422
Sequence_Interleaver<T>::Sequence_Interleaver
(ivec
in_interleaver_sequence
)
423
{
424
interleaver_depth =
in_interleaver_sequence
.
length
();
425
interleaver_sequence =
in_interleaver_sequence
;
426
input_length = 0;
427
}
428
429
template
<
class
T>
430
void
Sequence_Interleaver<T>::interleave
(
const
Vec<T>
&input,
Vec<T>
&output)
431
{
432
input_length = input.
length
();
433
int
steps
= (
int
)std::ceil(
double
(input_length) /
double
(interleaver_depth));
434
int
output_length
=
steps
* interleaver_depth;
435
output.
set_size
(
output_length
,
false
);
436
int
s,
i
;
437
438
if
(input_length ==
output_length
) {
439
440
//Sequence interleaver loop: All steps.
441
for
(s = 0; s <
steps
; s++) {
442
for
(
i
= 0;
i
< interleaver_depth;
i
++) {
443
output(s*interleaver_depth +
i
) = input(s * interleaver_depth + interleaver_sequence(
i
));
444
}
445
}
446
447
}
448
else
{
449
450
//Sequence interleaver loop: All, but the last, steps.
451
for
(s = 0; s <
steps
- 1; s++) {
452
for
(
i
= 0;
i
< interleaver_depth;
i
++) {
453
output(s*interleaver_depth +
i
) = input(s * interleaver_depth + interleaver_sequence(
i
));
454
}
455
}
456
//The last step.
457
Vec<T>
zerovect
(
output_length
- input_length);
458
zerovect
.clear();
459
Vec<T>
temp_last_input
=
concat
(input.
right
(interleaver_depth -
zerovect
.
length
()),
zerovect
);
460
for
(
i
= 0;
i
< interleaver_depth;
i
++) {
461
output((
steps
- 1)*interleaver_depth +
i
) =
temp_last_input
(interleaver_sequence(
i
));
462
}
463
464
}
465
}
466
467
template
<
class
T>
468
Vec<T>
Sequence_Interleaver<T>::interleave
(
const
Vec<T>
&input)
469
{
470
Vec<T>
output;
471
interleave(input, output);
472
return
output;
473
}
474
475
template
<
class
T>
476
void
Sequence_Interleaver<T>::deinterleave
(
const
Vec<T>
&input,
Vec<T>
&output,
short
keepzeros
)
477
{
478
int
thisinput_length
= input.
length
();
479
int
steps
= (
int
)std::ceil(
double
(
thisinput_length
) /
double
(interleaver_depth));
480
int
output_length
=
steps
* interleaver_depth;
481
output.
set_length
(
output_length
,
false
);
482
int
s,
i
;
483
484
if
(
thisinput_length
==
output_length
) {
485
486
//Sequence interleaver loop: All steps.
487
for
(s = 0; s <
steps
; s++) {
488
for
(
i
= 0;
i
< interleaver_depth;
i
++) {
489
output(s*interleaver_depth + interleaver_sequence(
i
)) = input(s * interleaver_depth +
i
);
490
}
491
}
492
493
}
494
else
{
495
//Sequence interleaver loop: All, but the last, steps.
496
for
(s = 0; s <
steps
- 1; s++) {
497
for
(
i
= 0;
i
< interleaver_depth;
i
++) {
498
output(s*interleaver_depth + interleaver_sequence(
i
)) = input(s * interleaver_depth +
i
);
499
}
500
}
501
//The last step.
502
Vec<T>
zerovect
(
output_length
-
thisinput_length
);
503
zerovect
.clear();
504
Vec<T>
temp_last_input
=
concat
(input.
right
(interleaver_depth -
zerovect
.
length
()),
zerovect
);
505
for
(
i
= 0;
i
< interleaver_depth;
i
++) {
506
output((
steps
- 1)*interleaver_depth + interleaver_sequence(
i
)) =
temp_last_input
(
i
);
507
}
508
if
(
keepzeros
== 0)
509
output.
set_size
(input_length,
true
);
510
}
511
512
}
513
514
template
<
class
T>
515
Vec<T>
Sequence_Interleaver<T>::deinterleave
(
const
Vec<T>
&input,
short
keepzeros
)
516
{
517
Vec<T>
output;
518
deinterleave(input, output,
keepzeros
);
519
return
output;
520
}
521
522
template
<
class
T>
523
void
Sequence_Interleaver<T>::randomize_interleaver_sequence
()
524
{
525
interleaver_sequence = sort_index(
randu
(interleaver_depth));
526
}
527
528
template
<
class
T>
529
ivec
Sequence_Interleaver<T>::get_interleaver_sequence
()
530
{
531
return
interleaver_sequence;
532
}
533
534
template
<
class
T>
535
void
Sequence_Interleaver<T>::set_interleaver_sequence
(ivec
in_interleaver_sequence
)
536
{
537
interleaver_sequence =
in_interleaver_sequence
;
538
interleaver_depth = interleaver_sequence.
size
();
539
}
540
542
543
// ----------------------------------------------------------------------
544
// Instantiations
545
// ----------------------------------------------------------------------
546
547
ITPP_EXPORT_TEMPLATE
template
class
ITPP_EXPORT
Block_Interleaver<double>
;
548
ITPP_EXPORT_TEMPLATE
template
class
ITPP_EXPORT
Block_Interleaver<short>
;
549
ITPP_EXPORT_TEMPLATE
template
class
ITPP_EXPORT
Block_Interleaver<int>
;
550
ITPP_EXPORT_TEMPLATE
template
class
ITPP_EXPORT
Block_Interleaver<std::complex<double>
>;
551
ITPP_EXPORT_TEMPLATE
template
class
ITPP_EXPORT
Block_Interleaver<bin>
;
552
553
ITPP_EXPORT_TEMPLATE
template
class
ITPP_EXPORT
Cross_Interleaver<double>
;
554
ITPP_EXPORT_TEMPLATE
template
class
ITPP_EXPORT
Cross_Interleaver<short>
;
555
ITPP_EXPORT_TEMPLATE
template
class
ITPP_EXPORT
Cross_Interleaver<int>
;
556
ITPP_EXPORT_TEMPLATE
template
class
ITPP_EXPORT
Cross_Interleaver<std::complex<double>
>;
557
ITPP_EXPORT_TEMPLATE
template
class