void map_punctured<libbase::vector, dbl>::dotransform(const array1i_t& in, array1i_t& out) const { // final vector size depends on the number of set positions assertalways(in.size() == pattern.size()); out.init(This::output_block_size()); // puncture the results for (int i = 0, ii = 0; i < in.size(); i++) if (pattern(i)) out(ii++) = in(i); }
template <class GF_q, class real> void linear_code_utils<GF_q, real>::encode_cw( const matrix<GF_q> & mat_G, const array1i_t & source, array1i_t & encoded) { #if DEBUG>=2 libbase::trace << std::endl << "encoding"; #endif //initialise encoded int length_n = mat_G.size().cols(); int dim_k = mat_G.size().rows(); assertalways(dim_k == source.size().length()); encoded.init(length_n); for (int i = 0; i < length_n; i++) { GF_q val = GF_q(0); for (int j = 0; j < dim_k; j++) { val += GF_q(source(j)) * mat_G(j, i); } encoded(i) = val; } #if DEBUG>=2 libbase::trace << std::endl << "finished encoding"; #endif }
void sum_prod_alg_trad<GF_q, real>::compute_q_mn(int m, int n, const array1i_t & M_n) { //initialise some helper variables int num_of_elements = GF_q::elements(); array1d_t q_mn(this -> received_probs(n)); int m_dash = 0; int pos_m = M_n(m) - 1;//we count from 1; //compute q_mn(sym) = a_mxn * P_n(sym) * \prod_{m'\in M(n)\m} r_m'xn(0) for all sym in GF_q int size_of_M_n = M_n.size().length(); for (int loop_m = 0; loop_m < size_of_M_n; loop_m++) { if (m != loop_m) { m_dash = M_n(loop_m) - 1; //we start counting from zero for (int loop_e = 0; loop_e < num_of_elements; loop_e++) { q_mn(loop_e) *= this->marginal_probs(m_dash, n).r_mxn(loop_e); } } } //normalise the q_mxn's so that q_mxn_0+q_mxn_1=1 real a_nxm = q_mn.sum();//sum up the values in q_mn assertalways(a_nxm!=real(0)); q_mn /= a_nxm; //normalise //store the values this->marginal_probs(pos_m, n).q_mxn = q_mn; }
void map_dividing<libbase::vector, dbl, dbl2>::dotransform(const array1i_t& in, array1i_t& out) const { // Confirm input sequence to be of the correct length assertalways(in.size() == this->input_block_size()); // Create converter object and perform necessary transform libbase::symbol_converter<dbl,dbl2> converter(Base::M, Base::q); converter.divide_symbols(in, out); }
void sum_prod_alg_trad<GF_q, real>::compute_r_mn(int m, int n, const array1i_t & tmpN_m) { //the number of remaining symbols that can vary int num_of_var_syms = tmpN_m.size() - 1; int num_of_elements = GF_q::elements(); //for each check node we need to consider num_of_elements^num_of_var_symbols cases int num_of_cases = int(pow(num_of_elements, num_of_var_syms)); int pos_n = tmpN_m(n) - 1;//we count from 1; int bitmask = num_of_elements - 1; //only use the entries that are variable array1i_t rel_N_m; rel_N_m.init(num_of_var_syms); int indx = 0; for (int loop = 0; loop < num_of_var_syms; loop++) { if (indx == n) { indx++; } rel_N_m(loop) = tmpN_m(indx); indx++; } //go through all cases - this will use bitwise manipulation GF_q syndrome_sym = GF_q(0); GF_q h_m_n_dash; //GF_q h_m_n; GF_q tmp_chk_val; int int_sym_val; int bits; int pos_n_dash; real q_nm_prod = real(1.0); this->marginal_probs(m, pos_n).r_mxn = 0.0; GF_q check_value = this->marginal_probs(m, pos_n).val; for (int loop1 = 0; loop1 < num_of_cases; loop1++) { bits = loop1; syndrome_sym = GF_q(0); q_nm_prod = 1.0; for (int loop2 = 0; loop2 < num_of_var_syms; loop2++) { pos_n_dash = rel_N_m(loop2) - 1;//we count from zero //extract int value of the first symbol int_sym_val = bits & bitmask; //shift bits to the right by the dimension of the finite field bits = bits >> GF_q::dimension(); //the parity check symbol at this position h_m_n_dash = this->marginal_probs(m, pos_n_dash).val; //compute the value that at this check tmp_chk_val = h_m_n_dash * GF_q(int_sym_val); //add it to the syndrome syndrome_sym = syndrome_sym + tmp_chk_val; //look up the prob that the chk_val was actually sent q_nm_prod *= this->marginal_probs(m, pos_n_dash).q_mxn(int_sym_val); } //adjust the appropriate rmn value int_sym_val = syndrome_sym / check_value; this->marginal_probs(m, pos_n).r_mxn(int_sym_val) += q_nm_prod; } }