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 // 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(bits2symbols); 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(bits2symbols); 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 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 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 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 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 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 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 the soft bit mapping matrices S0 and S1 00400 calculate_softbit_matrices(bits2symbols); 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(bits2symbols); 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 Sep 14 18:57:04 2008 for IT++ by Doxygen 1.5.6