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 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);
   }
Exemple #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;
   }
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);
   }
template <class GF_q, class real> void linear_code_utils<GF_q, real>::compute_dual_code(
      const matrix<GF_q> & orgMat, matrix<GF_q> & dualCodeGenMatrix,
      array1i_t & systematic_perm)
   {
   int length_n = orgMat.size().cols();
   int dim_k = orgMat.size().rows();
   int dim_m = length_n - dim_k;
   matrix<GF_q> refOrgMat;
#if DEBUG>=2
   std::cout << "The original matrix is given by:" << std::endl;
   orgMat.serialize(std::cout, '\n');
#endif
   linear_code_utils::compute_row_dim(orgMat, refOrgMat);

   dim_k = refOrgMat.size().rows();
   dim_m = length_n - dim_k;

   // Now we need to check that the columns are systematic
   //if they aren't then we need to perform some column permutation
   //otherwise the permutation is simple the identy map

   systematic_perm.init(length_n);
   for (int loop1 = 0; loop1 < length_n; loop1++)
      {
      //the identity permutation
      systematic_perm(loop1) = loop1;
      }

   bool needsPermutation =
         !(libbase::linear_code_utils<GF_q, real>::is_systematic(refOrgMat));
   if (needsPermutation)
      {
      //matrix needs its columns permuted before it is in systematic form
      //find the pivots
      int col_pos = 0;
      for (int loop1 = 0; loop1 < dim_k; loop1++)
         {

         while ((GF_q(1)) != refOrgMat(loop1, col_pos))
            {
            col_pos++;
            }
         std::swap(systematic_perm(loop1), systematic_perm(col_pos));
         col_pos++;
         }
#if DEBUG>=2
      std::cout << std::endl << "The permutation is given by:" << std::endl;
      systematic_perm.serialize(std::cout, ' ');
#endif
      if (needsPermutation)
         {
         //rejig the matrix
         matrix<GF_q> tmprefMatrix;
         tmprefMatrix.init(dim_k, length_n);
         int col_index;
         for (int loop1 = 0; loop1 < length_n; loop1++)
            {
            col_index = systematic_perm(loop1);
            tmprefMatrix.insertcol(refOrgMat.extractcol(col_index), loop1);
            }
         refOrgMat = tmprefMatrix;
         }
      }
   //the matrix should now be in the right format
#if DEBUG>=2
   std::cout << "After permuting any columns, the matrix is now given by:" << std::endl;
   refOrgMat.serialize(std::cout, '\n');
#endif

   //extract the P part of G'=(I_k|P)
   matrix<GF_q> tmp_p_mat;
   tmp_p_mat.init(dim_k, dim_m);

   for (int loop = dim_k; loop < length_n; loop++)
      {
      tmp_p_mat.insertcol(refOrgMat.extractcol(loop), loop - dim_k);
      }

   //this will hold -P^t=P^t (as we are in char GF(q)=2)
   matrix<GF_q> tmp_p_mat_t;
   tmp_p_mat_t.init(dim_m, length_n - dim_m);
   //now transpose yourself
   tmp_p_mat_t = tmp_p_mat.transpose();
   matrix<GF_q> id_m = matrix<GF_q>::eye(dim_m);

   //Construct the dual code gen matrix which is of the form
   //H=(-P^t|I_m)
   dualCodeGenMatrix.init(dim_m, length_n);

   //insert the transposed matrix
   for (int loop = 0; loop < (length_n - dim_m); loop++)
      {
      dualCodeGenMatrix.insertcol(tmp_p_mat_t.extractcol(loop), loop);
      }

   //now add the identity matrix
   int counter = 0;
   for (int loop = (length_n - dim_m); loop < length_n; loop++)
      {
      dualCodeGenMatrix.insertcol(id_m.extractcol(counter), loop);
      counter++;
      }

#if DEBUG>=2
   std::cout << "The generator matrix of the permuted dual code is given by:" << std::endl;
   dualCodeGenMatrix.serialize(std::cout, '\n');
#endif

   //undo any permutation that we did
   if (needsPermutation)
      {

      matrix<GF_q> tmpdualCodeGenMatrix;
      tmpdualCodeGenMatrix.init(dim_m, length_n);
      int col_index;
      for (int loop1 = 0; loop1 < length_n; loop1++)
         {
         col_index = systematic_perm(loop1);
         tmpdualCodeGenMatrix.insertcol(dualCodeGenMatrix.extractcol(loop1),
               col_index);
         }
      dualCodeGenMatrix = tmpdualCodeGenMatrix;
      }

#if DEBUG>=2
   std::cout
   << "After undoing the permutation, the generator matrix of the dual code is given by:" << std::endl;
   dualCodeGenMatrix.serialize(std::cout, '\n');
#endif

#if DEBUG>=2
   std::cout
   << "we now multiply the generator matrix by the transpose of the original matrix, ie:" << std::endl;
   std::cout << "the transpose of:" << std::endl;
   orgMat.serialize(std::cout, '\n');
   std::cout << "is:" << std::endl;
   matrix<GF_q> trans(orgMat.transpose());
   trans.serialize(std::cout, '\n');
   matrix<GF_q> zeroTest(dualCodeGenMatrix*trans);
   std::cout << "the result is:" << std::endl;
   zeroTest.serialize(std::cout, '\n');
   assertalways(GF_q(0)==zeroTest.max());
#endif

   }
Exemple #6
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;
      }
   }