IT++ Logo

modulator.cpp

Go to the documentation of this file.
00001 
00030 #include <itpp/comm/modulator.h>
00031 #include <itpp/comm/commfunc.h>
00032 #include <itpp/base/math/elem_math.h>
00033 #include <itpp/base/specmat.h>
00034 
00035 
00036 namespace itpp
00037 {
00038 
00039 
00040 // ----------------------------------------------------------------------
00041 // QAM
00042 // ----------------------------------------------------------------------
00043 
00044 void QAM::set_M(int Mary)
00045 {
00046   k = levels2bits(Mary);
00047   M = Mary;
00048   it_assert((pow2i(k) == M) && (is_even(k)),
00049             "QAM::set_M(): M = " << M << " is not an even power of 2");
00050   L = round_i(std::sqrt(static_cast<double>(M)));
00051 
00052   double average_energy = (M - 1) * 2.0 / 3.0;
00053   scaling_factor = std::sqrt(average_energy);
00054 
00055   symbols.set_size(M);
00056   bitmap.set_size(M, k);
00057   bits2symbols.set_size(M);
00058 
00059   bmat gray_code = graycode(levels2bits(L));
00060 
00061   for (int i = 0; i < L; i++) {
00062     for (int j = 0; j < L; j++) {
00063       symbols(i*L + j) = std::complex<double>(((L - 1) - j * 2) / scaling_factor,
00064                                               ((L - 1) - i * 2) / scaling_factor);
00065       bitmap.set_row(i*L + j, concat(gray_code.get_row(i),
00066                                      gray_code.get_row(j)));
00067       bits2symbols(bin2dec(bitmap.get_row(i*L + j))) = i * L + j;
00068     }
00069   }
00070 
00071   calculate_softbit_matrices();
00072 
00073   setup_done = true;
00074 }
00075 
00076 
00077 void QAM::demodulate_bits(const cvec &signal, bvec &out) const
00078 {
00079   it_assert_debug(setup_done, "QAM::demodulate_bits(): Modulator not ready.");
00080   out.set_size(k*signal.size(), false);
00081 
00082   int temp_real, temp_imag;
00083 
00084   for (int i = 0; i < signal.size(); i++) {
00085     temp_real = round_i((L - 1) - (std::real(signal(i) * scaling_factor)
00086                                    + (L - 1)) / 2.0);
00087     temp_imag = round_i((L - 1) - (std::imag(signal(i) * scaling_factor)
00088                                    + (L - 1)) / 2.0);
00089     if (temp_real < 0)
00090       temp_real = 0;
00091     else if (temp_real > (L - 1))
00092       temp_real = (L - 1);
00093     if (temp_imag < 0)
00094       temp_imag = 0;
00095     else if (temp_imag > (L - 1))
00096       temp_imag = (L - 1);
00097     out.replace_mid(k*i, bitmap.get_row(temp_imag * L + temp_real));
00098   }
00099 }
00100 
00101 bvec QAM::demodulate_bits(const cvec &signal) const
00102 {
00103   bvec out;
00104   demodulate_bits(signal, out);
00105   return out;
00106 }
00107 
00108 
00109 // ----------------------------------------------------------------------
00110 // PSK
00111 // ----------------------------------------------------------------------
00112 
00113 void PSK::set_M(int Mary)
00114 {
00115   k = levels2bits(Mary);
00116   M = Mary;
00117   it_assert(pow2i(k) == M, "PSK::set_M(): M is not a power of 2");
00118 
00119   symbols.set_size(M);
00120   bitmap = graycode(k);
00121   bits2symbols.set_size(M);
00122 
00123   double delta = m_2pi / M;
00124   double epsilon = delta / 10000.0;
00125   std::complex<double> symb;
00126   for (int i = 0; i < M; i++) {
00127     symb = std::complex<double>(std::polar(1.0, delta * i));
00128     if (std::fabs(std::real(symb)) < epsilon) {
00129       symbols(i) = std::complex<double>(0.0, std::imag(symb));
00130     }
00131     else if (std::fabs(std::imag(symb)) < epsilon) {
00132       symbols(i) = std::complex<double>(std::real(symb), 0.0);
00133     }
00134     else {
00135       symbols(i) = symb;
00136     }
00137 
00138     bits2symbols(bin2dec(bitmap.get_row(i))) = i;
00139   }
00140 
00141   calculate_softbit_matrices();
00142 
00143   setup_done = true;
00144 }
00145 
00146 
00147 void PSK::demodulate_bits(const cvec &signal, bvec &out) const
00148 {
00149   it_assert_debug(setup_done, "PSK::demodulate_bits(): Modulator not ready.");
00150   int est_symbol;
00151   double ang, temp;
00152 
00153   out.set_size(k*signal.size(), false);
00154 
00155   for (int i = 0; i < signal.size(); i++) {
00156     ang = std::arg(signal(i));
00157     temp = (ang < 0) ? (m_2pi + ang) : ang;
00158     est_symbol = round_i(temp * (M >> 1) / pi) % M;
00159     out.replace_mid(i*k, bitmap.get_row(est_symbol));
00160   }
00161 }
00162 
00163 bvec PSK::demodulate_bits(const cvec &signal) const
00164 {
00165   bvec out;
00166   demodulate_bits(signal, out);
00167   return out;
00168 }
00169 
00170 
00171 // ----------------------------------------------------------------------
00172 // QPSK
00173 // ----------------------------------------------------------------------
00174 
00175 void QPSK::demodulate_soft_bits(const cvec &rx_symbols, double N0,
00176                                 vec &soft_bits, Soft_Method) const
00177 {
00178   soft_bits.set_size(k * rx_symbols.size());
00179   std::complex<double> temp;
00180   double factor = 2 * std::sqrt(2.0) / N0;
00181   std::complex<double> exp_pi4 = std::complex<double>(std::cos(pi / 4),
00182                                  std::sin(pi / 4));
00183   for (int i = 0; i < rx_symbols.size(); i++) {
00184     temp = rx_symbols(i) * exp_pi4;
00185     soft_bits((i << 1) + 1) = std::real(temp) * factor;
00186     soft_bits(i << 1) = std::imag(temp) * factor;
00187   }
00188 }
00189 
00190 vec QPSK::demodulate_soft_bits(const cvec &rx_symbols, double N0,
00191                                Soft_Method method) const
00192 {
00193   vec out;
00194   demodulate_soft_bits(rx_symbols, N0, out, method);
00195   return out;
00196 }
00197 
00198 
00199 void QPSK::demodulate_soft_bits(const cvec &rx_symbols, const cvec &channel,
00200                                 double N0, vec &soft_bits,
00201                                 Soft_Method) const
00202 {
00203   soft_bits.set_size(2*rx_symbols.size(), false);
00204   std::complex<double> temp;
00205   double factor = 2 * std::sqrt(2.0) / N0;
00206   std::complex<double> exp_pi4 = std::complex<double>(std::cos(pi / 4),
00207                                  std::sin(pi / 4));
00208   for (int i = 0; i < rx_symbols.size(); i++) {
00209     temp = rx_symbols(i) * std::conj(channel(i)) * exp_pi4;
00210     soft_bits((i << 1) + 1) = std::real(temp) * factor;
00211     soft_bits(i << 1) = std::imag(temp) * factor;
00212   }
00213 }
00214 
00215 vec QPSK::demodulate_soft_bits(const cvec &rx_symbols, const cvec &channel,
00216                                double N0, Soft_Method method) const
00217 {
00218   vec out;
00219   demodulate_soft_bits(rx_symbols, channel, N0, out, method);
00220   return out;
00221 }
00222 
00223 
00224 // ----------------------------------------------------------------------
00225 // BPSK_c
00226 // ----------------------------------------------------------------------
00227 
00228 void BPSK_c::modulate_bits(const bvec &bits, cvec &out) const
00229 {
00230   out.set_size(bits.size(), false);
00231   for (int i = 0; i < bits.size(); i++) {
00232     out(i) = (bits(i) == 0 ? 1.0 : -1.0);
00233   }
00234 }
00235 
00236 cvec BPSK_c::modulate_bits(const bvec &bits) const
00237 {
00238   cvec out(bits.size());
00239   modulate_bits(bits, out);
00240   return out;
00241 }
00242 
00243 
00244 void BPSK_c::demodulate_bits(const cvec &signal, bvec &out) const
00245 {
00246   out.set_size(signal.size(), false);
00247   for (int i = 0; i < signal.length(); i++) {
00248     out(i) = (std::real(signal(i)) > 0) ? bin(0) : bin(1);
00249   }
00250 }
00251 
00252 bvec BPSK_c::demodulate_bits(const cvec &signal) const
00253 {
00254   bvec out(signal.size());
00255   demodulate_bits(signal, out);
00256   return out;
00257 }
00258 
00259 
00260 void BPSK_c::demodulate_soft_bits(const cvec &rx_symbols, double N0,
00261                                   vec &soft_bits, Soft_Method) const
00262 {
00263   double factor = 4 / N0;
00264   soft_bits.set_size(rx_symbols.size(), false);
00265 
00266   for (int i = 0; i < rx_symbols.size(); i++) {
00267     soft_bits(i) = factor * std::real(rx_symbols(i));
00268   }
00269 }
00270 
00271 vec BPSK_c::demodulate_soft_bits(const cvec &rx_symbols, double N0,
00272                                  Soft_Method method) const
00273 {
00274   vec out;
00275   demodulate_soft_bits(rx_symbols, N0, out, method);
00276   return out;
00277 }
00278 
00279 
00280 void BPSK_c::demodulate_soft_bits(const cvec &rx_symbols,
00281                                   const cvec &channel,
00282                                   double N0, vec &soft_bits,
00283                                   Soft_Method) const
00284 {
00285   double factor = 4 / N0;
00286   soft_bits.set_size(rx_symbols.size(), false);
00287 
00288   for (int i = 0; i < rx_symbols.size(); i++) {
00289     soft_bits(i) = factor * std::real(rx_symbols(i) * std::conj(channel(i)));
00290   }
00291 }
00292 
00293 vec BPSK_c::demodulate_soft_bits(const cvec &rx_symbols, const cvec &channel,
00294                                  double N0, Soft_Method method) const
00295 {
00296   vec out;
00297   demodulate_soft_bits(rx_symbols, channel, N0, out, method);
00298   return out;
00299 }
00300 
00301 
00302 // ----------------------------------------------------------------------
00303 // BPSK
00304 // ----------------------------------------------------------------------
00305 
00306 void BPSK::modulate_bits(const bvec &bits, vec &out) const
00307 {
00308   out.set_size(bits.size(), false);
00309   for (int i = 0; i < bits.size(); i++) {
00310     out(i) = (bits(i) == 0 ? 1.0 : -1.0);
00311   }
00312 }
00313 
00314 vec BPSK::modulate_bits(const bvec &bits) const
00315 {
00316   vec out(bits.size());
00317   modulate_bits(bits, out);
00318   return out;
00319 }
00320 
00321 
00322 void BPSK::demodulate_bits(const vec &signal, bvec &out) const
00323 {
00324   out.set_size(signal.size(), false);
00325   for (int i = 0; i < signal.length(); i++) {
00326     out(i) = (signal(i) > 0) ? bin(0) : bin(1);
00327   }
00328 }
00329 
00330 bvec BPSK::demodulate_bits(const vec &signal) const
00331 {
00332   bvec out(signal.size());
00333   demodulate_bits(signal, out);
00334   return out;
00335 }
00336 
00337 
00338 void BPSK::demodulate_soft_bits(const vec &rx_symbols, double N0,
00339                                 vec &soft_bits, Soft_Method) const
00340 {
00341   double factor = 4 / N0;
00342   soft_bits.set_size(rx_symbols.size(), false);
00343 
00344   for (int i = 0; i < rx_symbols.size(); i++) {
00345     soft_bits(i) = factor * rx_symbols(i);
00346   }
00347 }
00348 
00349 vec BPSK::demodulate_soft_bits(const vec &rx_symbols, double N0,
00350                                Soft_Method method) const
00351 {
00352   vec out;
00353   demodulate_soft_bits(rx_symbols, N0, out, method);
00354   return out;
00355 }
00356 
00357 
00358 void BPSK::demodulate_soft_bits(const vec &rx_symbols, const vec &channel,
00359                                 double N0, vec &soft_bits,
00360                                 Soft_Method) const
00361 {
00362   double factor = 4 / N0;
00363   soft_bits.set_size(rx_symbols.size(), false);
00364 
00365   for (int i = 0; i < rx_symbols.size(); i++) {
00366     soft_bits(i) = factor * (rx_symbols(i) * channel(i));
00367   }
00368 }
00369 
00370 vec BPSK::demodulate_soft_bits(const vec &rx_symbols, const vec &channel,
00371                                double N0, Soft_Method method) const
00372 {
00373   vec out;
00374   demodulate_soft_bits(rx_symbols, channel, N0, out, method);
00375   return out;
00376 }
00377 
00378 
00379 // ----------------------------------------------------------------------
00380 // PAM_c
00381 // ----------------------------------------------------------------------
00382 
00383 void PAM_c::set_M(int Mary)
00384 {
00385   M = Mary;
00386   k = levels2bits(M);
00387   it_assert(pow2i(k) == M, "PAM_c::set_M(): M is not a power of 2");
00388 
00389   symbols.set_size(M, false);
00390   bits2symbols.set_size(M, false);
00391   bitmap = graycode(k);
00392   double average_energy = (sqr(M) - 1) / 3.0;
00393   scaling_factor = std::sqrt(average_energy);
00394 
00395   for (int i = 0; i < M; i++) {
00396     symbols(i) = ((M - 1) - i * 2) / scaling_factor;
00397     bits2symbols(bin2dec(bitmap.get_row(i))) = i;
00398   }
00399 
00400   calculate_softbit_matrices();
00401 
00402   setup_done = true;
00403 }
00404 
00405 
00406 void PAM_c::demodulate_bits(const cvec &signal, bvec &out) const
00407 {
00408   it_assert_debug(setup_done, "PAM_c::demodulate_bits(): Modulator not ready.");
00409   int est_symbol;
00410   out.set_size(k*signal.size(), false);
00411 
00412   for (int i = 0; i < signal.size(); i++) {
00413     est_symbol = round_i((M - 1) - (std::real(signal(i)) * scaling_factor
00414                                     + (M - 1)) / 2);
00415     if (est_symbol < 0)
00416       est_symbol = 0;
00417     else if (est_symbol > (M - 1))
00418       est_symbol = M - 1;
00419     out.replace_mid(i*k, bitmap.get_row(est_symbol));
00420   }
00421 }
00422 
00423 bvec PAM_c::demodulate_bits(const cvec &signal) const
00424 {
00425   bvec temp(signal.size());
00426   demodulate_bits(signal, temp);
00427   return temp;
00428 }
00429 
00430 
00431 void PAM_c::demodulate_soft_bits(const cvec &rx_symbols, double N0,
00432                                  vec &soft_bits, Soft_Method method) const
00433 {
00434   it_assert_debug(setup_done, "PAM_c::demodulate_soft_bits(): Modulator not ready.");
00435   double P0, P1, d0min, d1min, temp;
00436   vec metric(M);
00437 
00438   soft_bits.set_size(k * rx_symbols.size());
00439 
00440   if (method == LOGMAP) {
00441     for (int l = 0; l < rx_symbols.size(); l++) {
00442       for (int j = 0; j < M; j++) {
00443         metric(j) = std::exp(-sqr(std::real(rx_symbols(l) - symbols(j)))
00444                              / N0);
00445       }
00446       for (int i = 0; i < k; i++) {
00447         P0 = P1 = 0;
00448         for (int j = 0; j < (M >> 1); j++) {
00449           P0 += metric(S0(i, j));
00450           P1 += metric(S1(i, j));
00451         }
00452         soft_bits(l*k + i) = trunc_log(P0) - trunc_log(P1);
00453       }
00454     }
00455   }
00456   else { // method == APPROX
00457     for (int l = 0; l < rx_symbols.size(); l++) {
00458       for (int j = 0; j < M; j++) {
00459         metric(j) = sqr(std::real(rx_symbols(l) - symbols(j)));
00460       }
00461       for (int i = 0; i < k; i++) {
00462         d0min = d1min = std::numeric_limits<double>::max();
00463         for (int j = 0; j < (M >> 1); j++) {
00464           temp = metric(S0(i, j));
00465           if (temp < d0min) { d0min = temp; }
00466           temp = metric(S1(i, j));
00467           if (temp < d1min) { d1min = temp; }
00468         }
00469         soft_bits(l*k + i) = (-d0min + d1min) / N0;
00470       }
00471     }
00472   }
00473 }
00474 
00475 vec PAM_c::demodulate_soft_bits(const cvec &rx_symbols, double N0,
00476                                 Soft_Method method) const
00477 {
00478   vec out;
00479   demodulate_soft_bits(rx_symbols, N0, out, method);
00480   return out;
00481 }
00482 
00483 
00484 void PAM_c::demodulate_soft_bits(const cvec &rx_symbols, const cvec &channel,
00485                                  double N0, vec &soft_bits,
00486                                  Soft_Method method) const
00487 {
00488   it_assert_debug(setup_done, "PAM_c::demodulate_soft_bits(): Modulator not ready.");
00489   double P0, P1, d0min, d1min, temp;
00490   vec metric(M);
00491 
00492   soft_bits.set_size(k * rx_symbols.size());
00493 
00494   if (method == LOGMAP) {
00495     for (int l = 0; l < rx_symbols.size(); l++) {
00496       for (int j = 0; j < M; j++) {
00497         metric(j) = std::exp(-sqr(std::real(rx_symbols(l)
00498                                             - channel(l) * symbols(j))) / N0);
00499       }
00500       for (int i = 0; i < k; i++) {
00501         P0 = P1 = 0;
00502         for (int j = 0; j < (M >> 1); j++) {
00503           P0 += metric(S0(i, j));
00504           P1 += metric(S1(i, j));
00505         }
00506         soft_bits(l*k + i) = trunc_log(P0) - trunc_log(P1);
00507       }
00508     }
00509   }
00510   else { // method == APPROX
00511     for (int l = 0; l < rx_symbols.size(); l++) {
00512       for (int j = 0; j < M; j++) {
00513         metric(j) = sqr(std::real(rx_symbols(l) - channel(l) * symbols(j)));
00514       }
00515       for (int i = 0; i < k; i++) {
00516         d0min = d1min = std::numeric_limits<double>::max();
00517         for (int j = 0; j < (M >> 1); j++) {
00518           temp = metric(S0(i, j));
00519           if (temp < d0min) { d0min = temp; }
00520           temp = metric(S1(i, j));
00521           if (temp < d1min) { d1min = temp; }
00522         }
00523         soft_bits(l*k + i) = (-d0min + d1min) / N0;
00524       }
00525     }
00526   }
00527 }
00528 
00529 vec PAM_c::demodulate_soft_bits(const cvec &rx_symbols, const cvec &channel,
00530                                 double N0, Soft_Method method) const
00531 {
00532   vec out;
00533   demodulate_soft_bits(rx_symbols, channel, N0, out, method);
00534   return out;
00535 }
00536 
00537 
00538 // ----------------------------------------------------------------------
00539 // PAM
00540 // ----------------------------------------------------------------------
00541 
00542 void PAM::set_M(int Mary)
00543 {
00544   M = Mary;
00545   k = levels2bits(M);
00546   it_assert(pow2i(k) == M, "PAM::set_M(): M is not a power of 2");
00547 
00548   symbols.set_size(M, false);
00549   bits2symbols.set_size(M, false);
00550   bitmap = graycode(k);
00551   double average_energy = (sqr(M) - 1) / 3.0;
00552   scaling_factor = std::sqrt(average_energy);
00553 
00554   for (int i = 0; i < M; i++) {
00555     symbols(i) = ((M - 1) - i * 2) / scaling_factor;
00556     bits2symbols(bin2dec(bitmap.get_row(i))) = i;
00557   }
00558 
00559   calculate_softbit_matrices();
00560 
00561   setup_done = true;
00562 }
00563 
00564 
00565 void PAM::demodulate_bits(const vec &signal, bvec &out) const
00566 {
00567   it_assert_debug(setup_done, "PAM::demodulate_bits(): Modulator not ready.");
00568   int est_symbol;
00569   out.set_size(k*signal.size(), false);
00570 
00571   for (int i = 0; i < signal.size(); i++) {
00572     est_symbol = round_i((M - 1) - (signal(i) * scaling_factor + (M - 1)) / 2);
00573     if (est_symbol < 0)
00574       est_symbol = 0;
00575     else if (est_symbol > (M - 1))
00576       est_symbol = M - 1;
00577     out.replace_mid(i*k, bitmap.get_row(est_symbol));
00578   }
00579 }
00580 
00581 bvec PAM::demodulate_bits(const vec &signal) const
00582 {
00583   bvec temp(signal.size());
00584   demodulate_bits(signal, temp);
00585   return temp;
00586 }
00587 
00588 } // namespace itpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
SourceForge Logo

Generated on Wed Mar 2 2011 22:05:03 for IT++ by Doxygen 1.7.3