37 #include <itpp/itexports.h> 92 virtual int get_k()
const {
return k; }
95 virtual int get_M()
const {
return M; }
120 virtual void modulate(
const ivec& symbolnumbers,
Vec<T>& output)
const;
225 double N0, vec& soft_bits,
281 setup_done(false), k(0), M(0), bitmap(
""), bits2symbols(
""), symbols(
""),
287 set(symbols, bits2symbols);
294 "Modulator<T>::set(): Number of symbols and bits2symbols does not match");
296 "Modulator<T>::set(): Number of symbols needs to be even and non-zero");
297 it_assert((
max(in_bits2symbols) == in_bits2symbols.size() - 1)
298 && (
min(in_bits2symbols) == 0),
"Modulator<T>::set(): Improper bits2symbol vector");
299 symbols = in_symbols;
300 bits2symbols = in_bits2symbols;
301 M = bits2symbols.
size();
303 bitmap.set_size(M, k);
304 for (
int m = 0; m < M; m++) {
305 bitmap.set_row(bits2symbols(m),
dec2bin(k, m));
307 calculate_softbit_matrices();
315 it_assert_debug(setup_done,
"Modulator<T>::modulate(): Modulator not ready.");
316 output.
set_size(symbolnumbers.length());
317 for (
int i = 0; i < symbolnumbers.length(); i++)
318 output(i) = symbols(symbolnumbers(i));
324 Vec<T> output(symbolnumbers.length());
325 modulate(symbolnumbers, output);
333 it_assert_debug(setup_done,
"Modulator<T>::demodulate(): Modulator not ready.");
334 double dist, mindist;
336 output.set_size(signal.
size());
338 for (
int i = 0; i < signal.
size(); i++) {
339 mindist =
std::abs(symbols(0) - signal(i));
341 for (
int j = 1; j < M; j++) {
342 dist =
std::abs(symbols(j) - signal(i));
343 if (dist < mindist) {
356 demodulate(signal, output);
364 it_assert_debug(setup_done,
"Modulator<T>::modulate_bits(): Modulator not ready.");
367 if (bits.length() % k) {
368 it_warning(
"Modulator<T>::modulate_bits(): The number of input bits is not a multiple of k (number of bits per symbol). Remainder bits are not modulated.");
370 int no_symbols = bits.length() / k;
372 for (
int i = 0; i < no_symbols; i++) {
373 output(i) = symbols(bits2symbols(
bin2dec(bits.mid(i * k, k))));
381 modulate_bits(bits, output);
388 it_assert_debug(setup_done,
"Modulator<T>::demodulate_bist(): Modulator not ready.");
389 double dist, mindist;
391 bits.set_size(k*signal.
size());
393 for (
int i = 0; i < signal.
size(); i++) {
394 mindist =
std::abs(symbols(0) - signal(i));
396 for (
int j = 1; j < M; j++) {
397 dist =
std::abs(symbols(j) - signal(i));
398 if (dist < mindist) {
403 bits.replace_mid(i*k, bitmap.get_row(closest));
411 demodulate_bits(signal, bits);
421 it_assert_debug(setup_done,
"Modulator<T>::demodulate_soft_bits(): Modulator not ready.");
422 double P0, P1, d0min, d1min, temp;
425 soft_bits.set_size(k * rx_symbols.
size());
428 for (
int l = 0; l < rx_symbols.
size(); l++) {
429 for (
int j = 0; j < M; j++) {
430 metric(j) =
std::exp(-
sqr(rx_symbols(l) - symbols(j)) / N0);
432 for (
int i = 0; i < k; i++) {
434 for (
int j = 0; j < (M >> 1); j++) {
435 P0 += metric(S0(i, j));
436 P1 += metric(S1(i, j));
443 for (
int l = 0; l < rx_symbols.
size(); l++) {
444 for (
int j = 0; j < M; j++) {
445 metric(j) =
sqr(rx_symbols(l) - symbols(j));
447 for (
int i = 0; i < k; i++) {
449 for (
int j = 0; j < (M >> 1); j++) {
450 temp = metric(S0(i, j));
451 if (temp < d0min) { d0min = temp; }
452 temp = metric(S1(i, j));
453 if (temp < d1min) { d1min = temp; }
455 soft_bits(l*k + i) = (-d0min + d1min) / N0;
467 demodulate_soft_bits(rx_symbols, N0, output, method);
473 const Vec<T> &channel,
double N0,
477 it_assert_debug(setup_done,
"Modulator_2D::demodulate_soft_bits(): Modulator not ready.");
478 double P0, P1, d0min, d1min, temp;
481 soft_bits.set_size(k * rx_symbols.
size());
484 for (
int l = 0; l < rx_symbols.
size(); l++) {
485 for (
int j = 0; j < M; j++) {
486 metric(j) =
std::exp(-
sqr(rx_symbols(l) - channel(l) * symbols(j))
489 for (
int i = 0; i < k; i++) {
491 for (
int j = 0; j < (M >> 1); j++) {
492 P0 += metric(S0(i, j));
493 P1 += metric(S1(i, j));
500 for (
int l = 0; l < rx_symbols.
size(); l++) {
501 for (
int j = 0; j < M; j++) {
502 metric(j) =
sqr(rx_symbols(l) - channel(l) * symbols(j));
504 for (
int i = 0; i < k; i++) {
506 for (
int j = 0; j < (M >> 1); j++) {
507 temp = metric(S0(i, j));
508 if (temp < d0min) { d0min = temp; }
509 temp = metric(S1(i, j));
510 if (temp < d1min) { d1min = temp; }
512 soft_bits(l*k + i) = (-d0min + d1min) / N0;
525 demodulate_soft_bits(rx_symbols, channel, N0, output, method);
535 S0.set_size(k, M >> 1,
false);
536 S1.set_size(k, M >> 1,
false);
538 for (
int i = 0; i < k; i++) {
541 for (
int j = 0; j < M; j++) {
542 if (bitmap(j, i) ==
bin(0)) {
737 const cvec& channel,
double N0,
839 const cvec& channel,
double N0,
937 const vec& channel,
double N0,
1070 const cvec& channel,
double N0,
1075 const cvec& channel,
double N0,
1128 #endif // #ifndef MODULATOR_H int size() const
The size of the vector.
PAM()
Default Constructor.
double scaling_factor
Scaling factor used to normalize the average energy to 1.
QAM()
Default Constructor.
PSK(int M)
Class constructor.
virtual ivec get_bits2symbols() const
Get the bitmap, which maps input bits into symbols.
General modulator for 1D or 2D signal constellations.
virtual void demodulate(const Vec< T > &signal, ivec &output) const
Demodulation of symbols.
int L
The square-root of M.
int k
Number of bits per modulation symbol.
PAM_c()
Default Constructor.
double scaling_factor
Scaling factor of square QAM constellation (sqrt((M-1)*2/3))
virtual void modulate_bits(const bvec &bits, Vec< T > &output) const
Modulation of bits.
bool is_even(int x)
Return true if x is an even integer.
virtual void demodulate_bits(const Vec< T > &signal, bvec &bits) const
Hard demodulation of bits.
int M
Number of modulation symbols.
virtual int bits_per_symbol() const
Returns number of bits per symbol.
virtual ~PSK()
Destructor.
Vec< bin > bvec
Definition of binary vector type.
virtual void modulate(const ivec &symbolnumbers, Vec< T > &output) const
Modulation of symbols.
BPSK modulator with real symbols.
void set_size(int size, bool copy=false)
Set length of vector. if copy = true then keeping the old values.
#define it_assert(t, s)
Abort if t is not true.
Logarithmic and exponenential functions - header file.
virtual ~Modulator()
Destructor.
Minimum and maximum functions on vectors and matrices.
QAM(int M)
Class Constructor.
#define it_assert_debug(t, s)
Abort if t is not true and NDEBUG is not defined.
Approximate faster method.
Vec< T > symbols
Corresponding modulation symbols (size: M)
imat S0
Matrix where row k contains the constellation points with '0' in bit position k.
BPSK modulator with complex symbols.
virtual ~PAM()
Destructor.
virtual ~PAM_c()
Destructor.
Definitions of converters between different vector and matrix types.
T min(const Vec< T > &in)
Minimum value of vector.
M-ary PAM modulator with real symbols.
M-ary QAM modulator with square lattice.
double scaling_factor
Scaling factor used to normalize the average energy to 1.
Matrix Class Definitions.
vec exp(const vec &x)
Exp of the elements of a vector x.
T max(const Vec< T > &v)
Maximum value of vector.
Modulator< std::complex< double > > Modulator_2D
Definition of 2D Modulator (with complex symbols)
double trunc_log(double x)
Truncated natural logarithm function.
PSK()
Default Constructor.
virtual int get_M() const
Returns number of modulation symbols.
M-ary PAM modulator with complex symbols.
virtual ~QPSK()
Destructor.
Modulator()
Default constructor.
ITPP_EXPORT bvec dec2bin(int length, int index)
Convert a decimal int index to bvec using length bits in the representation.
int length() const
The size of the vector.
Modulator< double > Modulator_1D
Definition of 1D Modulator (with real symbols)
vec sqr(const cvec &data)
Absolute square of elements.
Soft_Method
Soft demodulation methods.
#define it_warning(s)
Display a warning message.
void calculate_softbit_matrices()
This function calculates the soft bit mapping matrices S0 and S1.
Binary arithmetic (boolean) class.
virtual ~BPSK()
Destructor.
Log-MAP full calculation.
Vec< int > ivec
Definition of integer vector type.
virtual ~QAM()
Destructor.
bin abs(const bin &inbin)
absolute value of bin
virtual int get_k() const
Returns number of bits per symbol.
virtual ~BPSK_c()
Destructor.
void demodulate_bits(const cvec &signal, bvec &bits) const
Hard demodulation of bits.
ITPP_EXPORT int bin2dec(const bvec &inbvec, bool msb_first=true)
Convert a bvec to decimal int with the first bit as MSB if msb_first == true.
bmat bitmap
Bit to symbol mapping table (size: M x k)
Elementary mathematical functions - header file.
virtual Vec< T > get_symbols() const
Get the symbol values used in the modulator.
imat S1
Matrix where row k contains the constellation points with '1' in bit position k.
bool setup_done
Setup indicator.
int levels2bits(int n)
Calculate the number of bits needed to represent n different values (levels).
Vec< double > vec
Definition of double vector type.
virtual void demodulate_soft_bits(const Vec< T > &rx_symbols, double N0, vec &soft_bits, Soft_Method method=LOGMAP) const
Soft demodulator for AWGN channels.
Mat< bin > bmat
bin matrix
ivec bits2symbols
Bit to symbol mapping in decimal form (size: M)