interleave.h
Go to the documentation of this file.
#ifndef INTERLEAVE_H
#define INTERLEAVE_H
#include <itpp/base/vec.h>
#include <itpp/base/mat.h>
#include <itpp/base/random.h>
#include <itpp/base/sort.h>
#include <itpp/itexports.h>
namespace itpp
{
template <class T>
class Block_Interleaver
{
public:
Block_Interleaver(void) {rows = 0; cols = 0;};
Block_Interleaver(int in_rows, int in_cols);
Vec<T> interleave(const Vec<T> &input);
void interleave(const Vec<T> &input, Vec<T> &output);
Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
void set_rows(int in_rows) {rows = in_rows;};
void set_cols(int in_cols) {cols = in_cols;};
int get_rows(void) {return rows;};
int get_cols(void) {return cols;};
private:
int rows, cols, input_length;
};
template <class T>
class Cross_Interleaver
{
public:
Cross_Interleaver(void) {order = 0;};
Cross_Interleaver(int in_order);
Vec<T> interleave(const Vec<T> &input);
void interleave(const Vec<T> &input, Vec<T> &output);
Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
void set_order(int in_order);
int get_order(void) {return order;};
private:
int order;
int input_length;
Mat<T> inter_matrix;
Vec<T> tempvec, zerostemp;
};
template <class T>
class Sequence_Interleaver
{
public:
Sequence_Interleaver(void) {interleaver_depth = 0;};
Sequence_Interleaver(int in_interleaver_depth);
Sequence_Interleaver(ivec in_interleaver_sequence);
Vec<T> interleave(const Vec<T> &input);
void interleave(const Vec<T> &input, Vec<T> &output);
Vec<T> deinterleave(const Vec<T> &input, short keepzeros = 0);
void deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros = 0);
void randomize_interleaver_sequence();
ivec get_interleaver_sequence();
void set_interleaver_sequence(ivec in_interleaver_sequence);
void set_interleaver_depth(int in_interleaver_depth) { interleaver_depth = in_interleaver_depth; };
int get_interleaver_depth(void) { return interleaver_depth; };
private:
ivec interleaver_sequence;
int interleaver_depth, input_length;
};
//-----------------------------------------------------------------------------
// Implementation of templated members starts here
//-----------------------------------------------------------------------------
//-------------------------- Block Interleaver ---------------------------------
template<class T>
Block_Interleaver<T>::Block_Interleaver(int in_rows, int in_cols)
{
rows = in_rows;
cols = in_cols;
input_length = 0;
}
template<class T>
void Block_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
{
input_length = input.length();
int steps = (int)std::ceil(double(input_length) / double(rows * cols));
int output_length = steps * rows * cols;
output.set_length(output_length, false);
int s, r, c;
if (input_length == output_length) {
//Block interleaver loop: All steps.
for (s = 0; s < steps; s++) {
for (c = 0; c < cols; c++) {
for (r = 0; r < rows; r++) {
output(s*rows*cols + r*cols + c) = input(s * rows * cols + c * rows + r);
}
}
}
}
else {
//Block interleaver loop: All, but the last, steps.
for (s = 0; s < steps - 1; s++) {
for (c = 0; c < cols; c++) {
for (r = 0; r < rows; r++) {
output(s*rows*cols + r*cols + c) = input(s * rows * cols + c * rows + r);
}
}
}
//The last step.
Vec<T> zerovect(output_length - input_length);
zerovect.clear();
Vec<T> temp_last_input = concat(input.right(rows * cols - zerovect.length()), zerovect);
for (c = 0; c < cols; c++) {
for (r = 0; r < rows; r++) {
output((steps - 1)*rows*cols + r*cols + c) = temp_last_input(c * rows + r);
}
}
}
}
template<class T>
Vec<T> Block_Interleaver<T>::interleave(const Vec<T> &input)
{
Vec<T> output;
interleave(input, output);
return output;
}
template<class T>
void Block_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
{
int thisinput_length = input.length();
int steps = (int)std::ceil(double(thisinput_length) / double(rows * cols));
int output_length = steps * rows * cols;
output.set_size(output_length, false);
int s, r, c;
if (thisinput_length == output_length) {
//Block deinterleaver loop: All, but the last, steps.
for (s = 0; s < steps; s++) {
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
output(s*rows*cols + c*rows + r) = input(s * rows * cols + r * cols + c);
}
}
}
}
else {
//Block deinterleaver loop: All, but the last, steps.
for (s = 0; s < steps - 1; s++) {
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
output(s*rows*cols + c*rows + r) = input(s * rows * cols + r * cols + c);
}
}
}
//The last step.
Vec<T> zerovect(output_length - thisinput_length);
zerovect.clear();
Vec<T> temp_last_input = concat(input.right(rows * cols - zerovect.length()), zerovect);
for (r = 0; r < rows; r++) {
for (c = 0; c < cols; c++) {
output((steps - 1)*rows*cols + c*rows + r) = temp_last_input(r * cols + c);
}
}
}
if (keepzeros == 0)
output.set_size(input_length, true);
}
template<class T>
Vec<T> Block_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
{
Vec<T> output;
deinterleave(input, output, keepzeros);
return output;
}
//---------------------------- Cross Interleaver ---------------------------
template<class T>
Cross_Interleaver<T>::Cross_Interleaver(int in_order)
{
order = in_order;
input_length = 0;
inter_matrix.set_size(order, order, false);
tempvec.set_size(order, false);
zerostemp.set_size(order, false);
}
template<class T>
void Cross_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
{
input_length = input.length();
int steps = (int)std::ceil(float(input_length) / order) + order;
int output_length = steps * order;
output.set_length(output_length, false);
int i, r, c;
inter_matrix.clear();
zerostemp.clear();
//Cross interleaver loop:
for (i = 0; i < steps; i++) {
//Shift the matrix to the right:
for (c = order - 1; c > 0; c--)
inter_matrix.set_col(c, inter_matrix.get_col(c - 1));
// Write the new data to the matrix
if ((i*order + order) < input_length)
tempvec = input.mid(i * order, order);
else if ((i*order) < input_length)
tempvec = concat(input.right(input_length - i * order), zerostemp.left(order - (input_length - i * order)));
else
tempvec.clear();
inter_matrix.set_col(0, tempvec);
//Read the matrix diagonal-wise:
for (r = 0; r < order; r++)
output(i*order + r) = inter_matrix(r, r);
}
}
template<class T>
Vec<T> Cross_Interleaver<T>::interleave(const Vec<T> &input)
{
Vec<T> output;
interleave(input, output);
return output;
}
template<class T>
void Cross_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
{
int thisinput_length = input.length();
int steps = (int)std::ceil(float(thisinput_length) / order) + order;
int output_length = steps * order;
output.set_size(output_length, false);
int i, r, c;
inter_matrix.clear();
zerostemp.clear();
//Cross interleaver loop:
for (i = 0; i < steps; i++) {
//Shift the matrix to the right:
for (c = order - 1; c > 0; c--)
inter_matrix.set_col(c, inter_matrix.get_col(c - 1));
// Write the new data to the matrix
if ((i*order + order) < thisinput_length)
tempvec = input.mid(i * order, order);
else if ((i*order) < thisinput_length)
tempvec = concat(input.right(thisinput_length - i * order), zerostemp.left(order - (thisinput_length - i * order)));
else
tempvec.clear();
inter_matrix.set_col(0, tempvec);
//Read the matrix diagonal-wise:
for (r = 0; r < order; r++)
output(i*order + r) = inter_matrix(r, order - 1 - r);
}
if (keepzeros == 0)
output = output.mid(round_i(std::pow(double(order), 2)) - order, input_length);
}
template<class T>
Vec<T> Cross_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
{
Vec<T> output;
deinterleave(input, output, keepzeros);
return output;
}
template<class T>
void Cross_Interleaver<T>::set_order(int in_order)
{
order = in_order;
input_length = 0;
inter_matrix.set_size(order, order, false);
tempvec.set_size(order, false);
zerostemp.set_size(order, false);
}
//------------------- Sequence Interleaver --------------------------------
template<class T>
Sequence_Interleaver<T>::Sequence_Interleaver(int in_interleaver_depth)
{
interleaver_depth = in_interleaver_depth;
interleaver_sequence = sort_index(randu(in_interleaver_depth));
input_length = 0;
}
template<class T>
Sequence_Interleaver<T>::Sequence_Interleaver(ivec in_interleaver_sequence)
{
interleaver_depth = in_interleaver_sequence.length();
interleaver_sequence = in_interleaver_sequence;
input_length = 0;
}
template<class T>
void Sequence_Interleaver<T>::interleave(const Vec<T> &input, Vec<T> &output)
{
input_length = input.length();
int steps = (int)std::ceil(double(input_length) / double(interleaver_depth));
int output_length = steps * interleaver_depth;
output.set_size(output_length, false);
int s, i;
if (input_length == output_length) {
//Sequence interleaver loop: All steps.
for (s = 0; s < steps; s++) {
for (i = 0; i < interleaver_depth; i++) {
output(s*interleaver_depth + i) = input(s * interleaver_depth + interleaver_sequence(i));
}
}
}
else {
//Sequence interleaver loop: All, but the last, steps.
for (s = 0; s < steps - 1; s++) {
for (i = 0; i < interleaver_depth; i++) {
output(s*interleaver_depth + i) = input(s * interleaver_depth + interleaver_sequence(i));
}
}
//The last step.
Vec<T> zerovect(output_length - input_length);
zerovect.clear();
Vec<T> temp_last_input = concat(input.right(interleaver_depth - zerovect.length()), zerovect);
for (i = 0; i < interleaver_depth; i++) {
output((steps - 1)*interleaver_depth + i) = temp_last_input(interleaver_sequence(i));
}
}
}
template<class T>
Vec<T> Sequence_Interleaver<T>::interleave(const Vec<T> &input)
{
Vec<T> output;
interleave(input, output);
return output;
}
template<class T>
void Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, Vec<T> &output, short keepzeros)
{
int thisinput_length = input.length();
int steps = (int)std::ceil(double(thisinput_length) / double(interleaver_depth));
int output_length = steps * interleaver_depth;
output.set_length(output_length, false);
int s, i;
if (thisinput_length == output_length) {
//Sequence interleaver loop: All steps.
for (s = 0; s < steps; s++) {
for (i = 0; i < interleaver_depth; i++) {
output(s*interleaver_depth + interleaver_sequence(i)) = input(s * interleaver_depth + i);
}
}
}
else {
//Sequence interleaver loop: All, but the last, steps.
for (s = 0; s < steps - 1; s++) {
for (i = 0; i < interleaver_depth; i++) {
output(s*interleaver_depth + interleaver_sequence(i)) = input(s * interleaver_depth + i);
}
}
//The last step.
Vec<T> zerovect(output_length - thisinput_length);
zerovect.clear();
Vec<T> temp_last_input = concat(input.right(interleaver_depth - zerovect.length()), zerovect);
for (i = 0; i < interleaver_depth; i++) {
output((steps - 1)*interleaver_depth + interleaver_sequence(i)) = temp_last_input(i);
}
if (keepzeros == 0)
output.set_size(input_length, true);
}
}
template<class T>
Vec<T> Sequence_Interleaver<T>::deinterleave(const Vec<T> &input, short keepzeros)
{
Vec<T> output;
deinterleave(input, output, keepzeros);
return output;
}
template<class T>
void Sequence_Interleaver<T>::randomize_interleaver_sequence()
{
interleaver_sequence = sort_index(randu(interleaver_depth));
}
template<class T>
ivec Sequence_Interleaver<T>::get_interleaver_sequence()
{
return interleaver_sequence;
}
template<class T>
void Sequence_Interleaver<T>::set_interleaver_sequence(ivec in_interleaver_sequence)
{
interleaver_sequence = in_interleaver_sequence;
interleaver_depth = interleaver_sequence.size();
}
// ----------------------------------------------------------------------
// Instantiations
// ----------------------------------------------------------------------
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<double>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<short>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<int>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<std::complex<double> >;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Block_Interleaver<bin>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<double>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<short>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<int>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<std::complex<double> >;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Cross_Interleaver<bin>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<double>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<short>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<int>;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<std::complex<double> >;
ITPP_EXPORT_TEMPLATE template class ITPP_EXPORT Sequence_Interleaver<bin>;
} // namespace itpp
#endif // #ifndef INTERLEAVE_H
itpp::Array
General array class.
Definition array.h:105
itpp::Array::mid
Array< T > mid(int pos, int n) const
Get n elements of the array starting from pos.
Definition array.h:377
itpp::Array::set_length
void set_length(int n, bool copy=false)
Resizing an Array<T>.
Definition array.h:161
itpp::Array::size
int size() const
Returns the number of data elements in the array object.
Definition array.h:155
itpp::Array::left
Array< T > left(int n) const
Get n left elements of the array.
Definition array.h:357
itpp::Array::set_size
void set_size(int n, bool copy=false)
Resizing an Array<T>.
Definition array.h:257
itpp::Array::concat
friend const Array< T > concat(const Array< T > &a1, const T &e)
Append element e to the end of the Array a.
Definition array.h:486
itpp::Array::length
int length() const
Returns the number of data elements in the array object.
Definition array.h:157
itpp::Array::right
Array< T > right(int n) const
Get n right elements of the array.
Definition array.h:367
itpp::Block_Interleaver
Block Interleaver Class.
Definition interleave.h:62
itpp::Block_Interleaver::deinterleave
Vec< T > deinterleave(const Vec< T > &input, short keepzeros=0)
Function for block deinterleaving. Removes additional zeros if keepzeros = 0.
Definition interleave.h:296
itpp::Block_Interleaver::interleave
Vec< T > interleave(const Vec< T > &input)
Function for block interleaving. May add some zeros.
Definition interleave.h:246
itpp::Block_Interleaver::Block_Interleaver
Block_Interleaver(void)
Block_Interleaver constructor.
Definition interleave.h:65
itpp::Block_Interleaver::set_cols
void set_cols(int in_cols)
Set the number of columns for block interleaving.
Definition interleave.h:79
itpp::Block_Interleaver::get_rows
int get_rows(void)
Get the number of rows for block interleaving.
Definition interleave.h:81
itpp::Block_Interleaver::get_cols
int get_cols(void)
Get the number of columns for block interleaving.
Definition interleave.h:83
itpp::Block_Interleaver::set_rows
void set_rows(int in_rows)
Set the number of rows for block interleaving.
Definition interleave.h:77
itpp::Cross_Interleaver
Cross Interleaver Class.
Definition interleave.h:109
itpp::Cross_Interleaver::set_order
void set_order(int in_order)
Set the order of the Cross Interleaver.
Definition interleave.h:402
itpp::Cross_Interleaver::get_order
int get_order(void)
Get the order of the Cross Interleaver.
Definition interleave.h:126
itpp::Cross_Interleaver::Cross_Interleaver
Cross_Interleaver(void)
Cross_Interleaver constructor.
Definition interleave.h:112
itpp::Cross_Interleaver::deinterleave
Vec< T > deinterleave(const Vec< T > &input, short keepzeros=0)
Function for cross deinterleaving. Removes aditional zeros if keepzeros = 0.
Definition interleave.h:394
itpp::Cross_Interleaver::interleave
Vec< T > interleave(const Vec< T > &input)
Function for cross interleaving. Adds some zeros.
Definition interleave.h:350
itpp::Sequence_Interleaver
Sequence Interleaver Class.
Definition interleave.h:152
itpp::Sequence_Interleaver::set_interleaver_depth
void set_interleaver_depth(int in_interleaver_depth)
Set the length of the interleaver sequence to be used.
Definition interleave.h:183
itpp::Sequence_Interleaver::Sequence_Interleaver
Sequence_Interleaver(int in_interleaver_depth)
Sequence_Interleaver constructor.
Definition interleave.h:414
itpp::Sequence_Interleaver::interleave
Vec< T > interleave(const Vec< T > &input)
Function for sequence interleaving. May add some zeros.
Definition interleave.h:468
itpp::Sequence_Interleaver::Sequence_Interleaver
Sequence_Interleaver(ivec in_interleaver_sequence)
Sequence_Interleaver constructor.
Definition interleave.h:422
itpp::Sequence_Interleaver::Sequence_Interleaver
Sequence_Interleaver(void)
Sequence_Interleaver constructor.
Definition interleave.h:155
itpp::Sequence_Interleaver::deinterleave
Vec< T > deinterleave(const Vec< T > &input, short keepzeros=0)
Function for sequence deinterleaving. Removes additional zeros if keepzeros = 0.
Definition interleave.h:515
itpp::Sequence_Interleaver::get_interleaver_depth
int get_interleaver_depth(void)
Get the length of the interleaver sequence presently used.
Definition interleave.h:185
itpp::Sequence_Interleaver::deinterleave
void deinterleave(const Vec< T > &input, Vec< T > &output, short keepzeros=0)
Function for sequence deinterleaving. Removes additional zeros if keepzeros = 0.
Definition interleave.h:476
itpp::Sequence_Interleaver::get_interleaver_sequence
ivec get_interleaver_sequence()
Returns the interleaver sequence presently used.
Definition interleave.h:529
itpp::Sequence_Interleaver::set_interleaver_sequence
void set_interleaver_sequence(ivec in_interleaver_sequence)
Set the interleaver sequence to be used.
Definition interleave.h:535
itpp::Sequence_Interleaver::interleave
void interleave(const Vec< T > &input, Vec< T > &output)
Function for sequence interleaving. May add some zeros.
Definition interleave.h:430
itpp::Sequence_Interleaver::randomize_interleaver_sequence
void randomize_interleaver_sequence()
Generate a new random sequence for interleaving.
Definition interleave.h:523
itpp::randu
double randu(void)
Generates a random uniform (0,1) number.
Definition random.h:804
mat.h
Matrix Class Definitions.
itpp
itpp namespace
Definition itmex.h:37
itpp::round_i
ITPP_EXPORT int round_i(double x)
Round to nearest integer.
random.h
Definition of classes for random number generators.
sort.h
Sorting functions.
vec.h
Templated Vector Class Definitions.

Generated on Mon Jun 10 2024 11:49:20 for IT++ by Doxygen 1.9.8