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
Generated on Sun Jul 26 08:54:56 2009 for IT++ by Doxygen 1.5.9