ivec Ant1Relay::bpsk_nc_ml_demapping(Array<complex<double> > &miso_out, cvec symbols) { ivec res_label; res_label.set_size(miso_out.size()); for(int i=0; i<miso_out.size(); i++) { complex<double> Y = miso_out(i); cvec X = zeros_c(2); double min_norm = numeric_limits<double>::max(); int min_pt = -1; for(int q=0; q<symbols.size(); q++) { X(0) = symbols(q); for(int r=0; r<symbols.size(); r++) { X(1) = symbols(r); complex<double> hx = channel * X; double calc_norm = norm(Y-hx); if(calc_norm < min_norm) { min_norm = calc_norm; min_pt = (q^r) & 0x01; // xor } } } res_label(i) = min_pt; } return res_label; }
cvec operator-(const double &s, const cvec &v) { it_assert_debug(v.size() > 0, "operator-(): Vector of zero length"); cvec temp(v.size()); for (int i = 0;i < v.size();i++) { temp(i) = std::complex<double>((double)s - v(i).real(), -v(i).imag()); } return temp; }
cvec operator/(const double &s, const cvec &v) { it_assert_debug(v.size() > 0, "operator/(): Vector of zero length"); cvec temp(v.length()); for (int i = 0;i < v.size();i++) { temp(i) = s / v(i); } return temp; }
cvec operator/(const cvec &v, const double &s) { it_assert_debug(v.size() > 0, "operator/(): Vector of zero length"); cvec temp = v; for (int i = 0;i < v.size();i++) { temp(i) /= (double)s; } return temp; }
cvec polyval(const cvec &p, const vec &x) { it_error_if(p.size() == 0, "polyval: size of polynomial is zero"); it_error_if(x.size() == 0, "polyval: size of input value vector is zero"); cvec out(x.size()); out = p(0); for (int i = 1; i < p.size(); i++) out = std::complex<double>(p(i)) + elem_mult(to_cvec(x), out); return out; }
cvec polyval(const cvec &p, const cvec &x) { it_error_if(p.size() == 0, "polyval: size of polynomial is zero"); it_error_if(x.size() == 0, "polyval: size of input value vector is zero"); cvec out(x.size()); out = p(0); for (int i = 1; i < p.size(); i++) out = p(i) + elem_mult(x, out); return out; }
void roots(const cvec &p, cvec &r) { int n = p.size(), m, l; ivec f; // find all non-zero elements for (int i = 0; i < n; i++) if (p(i) != 0.0) f = concat(f, i); m = f.size(); cvec v = p; cmat A; if (m > 0 && n > 1) { v = v(f(0), f(m - 1)); l = v.size(); if (l > 1) { A = diag(ones_c(l - 2), -1); A.set_row(0, -v(1, l - 1) / v(0)); r = eig(A); if (f(m - 1) < n) r = concat(r, zeros_c(n - f(m - 1) - 1)); } else { r.set_size(n - f(m - 1) - 1, false); r.zeros(); } } else r.set_size(0, false); }
std::complex<double> operator*(const ivec &a, const cvec &b) { it_assert_debug(a.size() == b.size(), "operator*(): sizes does not match"); std::complex<double> temp = 0; for (int i = 0;i < a.size();i++) {temp += (double)a(i) * b(i);} return temp; }
cvec operator+(const ivec &a, const cvec &b) { it_assert_debug(a.size() == b.size(), "operator+(): sizes does not match"); cvec temp = b; for (int i = 0;i < a.size();i++) {temp(i) += (double)a(i);} return temp; }
void poly(const cvec &r, cvec &p) { int n = r.size(); p.set_size(n + 1, false); p.zeros(); p(0) = 1.0; for (int i = 0; i < n; i++) p.set_subvector(1, p(1, i + 1) - r(i)*p(0, i)); }
cvec operator*(const cmat &m, const cvec &v) { it_assert_debug(m.no_cols == v.size(), "cmat::operator*(): Wrong sizes"); cvec r(m.no_rows); std::complex<double> alpha = std::complex<double>(1.0); std::complex<double> beta = std::complex<double>(0.0); char trans = 'n'; int incr = 1; blas::zgemv_(&trans, &m.no_rows, &m.no_cols, &alpha, m.data, &m.no_rows, v._data(), &incr, &beta, r._data(), &incr); return r; }
void auto_correlation(const cvec &a, cvec &x) { int k = a.size(); x.set_size(k); for (int i = 0; i < k; ++i) { x[i] = 0; for (int j = 0; j < k - i; ++j) x[i] += a[j] * conj(a[j + i]); for (int j = k - i; j < k; ++j) x[i] += a[j] * conj(a[j - k + i]); } }
void Ant1Relay::init_sp_const(cvec &m1, cvec &m2) { // Generate the superimposed points int k = 0; cvec orin_pt = zeros_c(2); for(int i=0; i<m1.size(); i++) { orin_pt(0) = m1(i); for(int j=0; j<m2.size(); j++) { orin_pt(1) = m2(j); complex<double> pt = channel * orin_pt; int label = (i^j) & 0x03; // xor //cout<<i<<","<<j<<","<<label<<endl; sp_constellation(k).pt = pt; sp_constellation(k).label = label; k++; } } }
void BlindOFDM_UHDDevice::sendsamples(cvec tx_buff,double timestamp){ int num_tx_samps=0; tx_buff=tx_buff*tx_amplitude; tx_md.start_of_burst = true; tx_md.end_of_burst = true; tx_md.has_time_spec = true; tx_md.time_spec = uhd::time_spec_t(timestamp); //cout << "The time is now " << time() << endl; if(time()>timestamp) cout << "Timestamp not valid" << endl; //cout << "before sending " << time(); num_tx_samps=tx_stream->send(&tx_buff(0), tx_buff.size(), tx_md, timestamp+tx_buff.size()/tx_rate); //cout << "after sending " << time(); //cout << "Number of samples sent by the Tx streamer " << num_tx_samps << endl; }
cvec operator*(const cmat &m, const cvec &v) { it_assert_debug(m.no_cols == v.size(), "Mat<>::operator*(): Wrong sizes"); cvec r(m.no_rows); for (int i = 0; i < m.no_rows; i++) { r(i) = std::complex<double>(0.0); int m_pos = 0; for (int k = 0; k < m.no_cols; k++) { r(i) += m.data[m_pos+i] * v(k); m_pos += m.no_rows; } } return r; }
/** Channel unknown * ESE with CE */ Array<bvec> IdmaRx::receive(cvec &recv_sig, double noise_var, int no_taps) { LOG4CXX_DEBUG(logger, "IdmaRx::receive() with CE"); BPSK bpsk; int num_user = intls.size(); int len_recv = recv_sig.size(); int len_sym = len_recv - no_taps + 1; Array<bvec> est_bmsgs(num_user); LOG4CXX_TRACE(logger, "recv_sig="<<recv_sig); // TODO: To be modified if a convolutional code is not used int constraint_length = fec_wrap->get_constraint_length(); int len_msg = recv_sig.size() * 2 / len_spread * fec_wrap->get_rate(); if(constraint_length>0) len_msg -= constraint_length - 1; LOG4CXX_DEBUG(logger, "len_msg="<<len_msg); // initialize ese LOG4CXX_DEBUG(logger, "ce_init"); ese.ce_init(recv_sig, no_taps, noise_var); // Beginning from zero prior Array<vec> llr_priors(num_user); for(int i=0; i<llr_priors.size(); i++) llr_priors(i) = zeros(len_recv*2); // TODO: len_sp_spread // // Initialize ch_coeffs // Array<cmat> ch_coeffs(num_user); // for(int i=0; i<num_user; i++) { // ch_coeffs(i).set_size(len_sym, no_taps); // } /* Itarative decoding */ for(int iter=0; iter<num_iteration; iter++) { LOG4CXX_TRACE(logger, "================================================"); LOG4CXX_TRACE(logger, " ite="<<iter<<" "); LOG4CXX_TRACE(logger, "================================================"); for(int nuser=0; nuser<num_user; nuser++) { /* Channel estimation * Single-path and block fading channel only * TODO: multipath & time-varying channels */ #ifdef LI_CE cvec hval = ese.li_est_ch(nuser, llr_priors(nuser)); #else cvec hval = ese.est_ch(nuser, llr_priors(nuser)); #endif LOG4CXX_DEBUG(logger, "hval: "<<hval); /* SISO */ // TODO: check #ifdef GRAY_IDMA vec llr_ese = ese.ce_siso_user(nuser); #else vec llr_ese = ese.ce_siso_user(nuser, recv_sig, *pqam, llr_priors(nuser)); #endif check_llr(llr_ese); LOG4CXX_TRACE(logger, "llr_ese: "<<llr_ese); /* de-interleaving */ vec deintl_llr_ese = intls(nuser).deinterleave(llr_ese); LOG4CXX_TRACE(logger, "deintl_llr_ese: "<<deintl_llr_ese); /* despread */ vec desp_llr_prior = spreader.llr_despread(deintl_llr_ese); LOG4CXX_TRACE(logger, "desp_llr_prior: "<<desp_llr_prior); /* soft-decoding */ vec extrinsic_coded; vec extrinsic_data; vec appllr_coded; fec_wrap->inner_soft_decode(desp_llr_prior, extrinsic_coded, extrinsic_data, appllr_coded, true); /*with_padded*/ LOG4CXX_TRACE(logger, "extrinsic_coded="<<extrinsic_coded); LOG4CXX_TRACE(logger, "extrinsic_data="<<extrinsic_data); LOG4CXX_DEBUG(logger, "appllr_coded="<<appllr_coded); est_bmsgs(nuser) = bpsk.demodulate_bits(extrinsic_data).left(len_msg); // hard-decoding LOG4CXX_TRACE(logger, "est_bmsgs("<<nuser<<"): "<<est_bmsgs(nuser)); /* spread */ //vec llr_sp_dec = spreader.llr_spread(extrinsic_coded) - deintl_llr_ese; vec llr_sp_dec = spreader.llr_spread(appllr_coded) - deintl_llr_ese; LOG4CXX_TRACE(logger, "llr_sp_dec: "<<llr_sp_dec); /* interleaving */ llr_priors(nuser) = intls(nuser).interleave(llr_sp_dec); check_llr(llr_priors(nuser)); LOG4CXX_TRACE(logger, "llr_priors("<<nuser<<"): "<<llr_priors(nuser)); } mse.calculate(iter, ese.get_h()); } return est_bmsgs; }
/** Channel known * Original ESE with perfect CSI */ Array<bvec> IdmaRx::receive(cvec &recv_sig, Array<cmat> &ch_coeffs, double noise_var) { LOG4CXX_DEBUG(logger, "IdmaRx::receive()"); int no_taps = ch_coeffs(0).cols(); LOG4CXX_DEBUG(logger, "channel taps = " <<no_taps); BPSK bpsk; int num_user = intls.size(); int len_recv = recv_sig.size(); Array<bvec> est_bmsgs(num_user); // TODO: To be modified if a convolutional code is not used int constraint_length = fec_wrap->get_constraint_length(); int len_tx_sym = recv_sig.size() - no_taps + 1; int len_sp_codeword = len_tx_sym * pqam->bits_per_symbol(); int len_codeword = len_sp_codeword / len_spread; int len_msg = len_codeword * fec_wrap->get_rate(); if(constraint_length>0) len_msg -= constraint_length - 1; LOG4CXX_DEBUG(logger, "constraint_length="<<constraint_length); LOG4CXX_DEBUG(logger, "len_tx_sym="<<len_tx_sym); LOG4CXX_DEBUG(logger, "len_sp_codeword="<<len_sp_codeword); LOG4CXX_DEBUG(logger, "len_codeword="<<len_codeword); LOG4CXX_DEBUG(logger, "len_msg="<<len_msg); // initialize ese ese.recv_init(recv_sig, ch_coeffs, noise_var); // Beginning from zero prior Array<vec> llr_priors(num_user); for(int i=0; i<llr_priors.size(); i++) llr_priors(i) = zeros(len_sp_codeword); // TODO: len_sp_spread for(int iter=0; iter<num_iteration; iter++) { LOG4CXX_TRACE(logger, "================================================"); LOG4CXX_TRACE(logger, " ite="<<iter<<" "); LOG4CXX_TRACE(logger, "================================================"); for(int nuser=0; nuser<num_user; nuser++) { /* ESE */ #ifdef GRAY_IDMA vec llr_ese = ese.siso_user(nuser, llr_priors(nuser)); #else vec llr_ese = ese.siso_user(nuser, recv_sig, *pqam, llr_priors(nuser)); #endif check_llr(llr_ese); LOG4CXX_DEBUG(logger, "llr_ese: "<<llr_ese); /* de-interleaving */ vec deintl_llr_ese = intls(nuser).deinterleave(llr_ese); LOG4CXX_TRACE(logger, "deintl_llr_ese: "<<deintl_llr_ese); /* despread */ vec desp_llr_prior = spreader.llr_despread(deintl_llr_ese); check_llr(desp_llr_prior); LOG4CXX_TRACE(logger, "desp_llr_prior: "<<desp_llr_prior); /* soft-decoding */ vec extrinsic_coded; vec extrinsic_data; vec appllr_coded; fec_wrap->inner_soft_decode(desp_llr_prior, extrinsic_coded, extrinsic_data, appllr_coded, true); /*with_padded*/ LOG4CXX_TRACE(logger, "extrinsic_coded="<<extrinsic_coded); LOG4CXX_DEBUG(logger, "extrinsic_data="<<extrinsic_data); LOG4CXX_DEBUG(logger, "appllr_coded="<<appllr_coded); est_bmsgs(nuser) = bpsk.demodulate_bits(extrinsic_data).left(len_msg); // hard-decoding LOG4CXX_TRACE(logger, "est_bmsgs("<<nuser<<"): "<<est_bmsgs(nuser)); /* spread */ //vec llr_sp_dec = spreader.llr_spread(extrinsic_coded) - deintl_llr_ese; vec llr_sp_dec = spreader.llr_spread(appllr_coded) - deintl_llr_ese; LOG4CXX_DEBUG(logger, "llr_sp_dec: "<<llr_sp_dec); /* interleaving */ llr_priors(nuser) = intls(nuser).interleave(llr_sp_dec); check_llr(llr_priors(nuser)); LOG4CXX_TRACE(logger, "llr_priors("<<nuser<<"): "<<llr_priors(nuser)); } } return est_bmsgs; }