예제 #1
0
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
   }
예제 #3
0
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;
   }
예제 #4
0
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);
   }
예제 #5
0
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;
      }
   }