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