template <class GF_q, class real> void sum_prod_alg_abstract<GF_q, real>::compute_probs(
      array1vd_t& ro)
   {
   //ensure the output vector has the right length
   ro.init(this->length_n);

   //initialise some helper variables
   int num_of_elements = GF_q::elements();
   real a_n = real(0.0);
   int size_of_M_n = 0;
   int pos_m;
   for (int loop_n = 0; loop_n < this->length_n; loop_n++)
      {
      ro(loop_n) = this->received_probs(loop_n);
      size_of_M_n = this->M_n(loop_n).size();
      for (int loop_e = 0; loop_e < num_of_elements; loop_e++)
         {
         for (int loop_m = 0; loop_m < size_of_M_n; loop_m++)
            {
            pos_m = this->M_n(loop_n)(loop_m) - 1;//we count from 0
            ro(loop_n)(loop_e) *= this->marginal_probs(pos_m, loop_n).r_mxn(
                  loop_e);
            }
         //Use appropriate clipping method
         perform_clipping(ro(loop_n)(loop_e));
         }
      //Note the following step is not strictly necessary apart from making the result
      //look neater - however it only adds a small overhead

      //normalise the result so that q_n_0+q_n_1=1
      a_n = ro(loop_n).sum();
      assertalways(a_n!=real(0.0));
      ro(loop_n) /= a_n;
      }
   }
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
   }
Beispiel #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;
   }
Beispiel #4
0
void sum_prod_alg_trad<GF_q, real>::spa_init(const array1vd_t& recvd_probs)
   {

   //initialise the marginal prob values
   int num_of_elements = GF_q::elements();
   real tmp_prob = real(0.0);
   real alpha = real(0.0);

   //ensure we don't have zero probabilities
   //and normalise the probs at the same time

   this->received_probs.init(recvd_probs.size());
   for (int loop_n = 0; loop_n < this->length_n; loop_n++)
      {
      this->received_probs(loop_n).init(num_of_elements);
      alpha = real(0.0);
      for (int loop_e = 0; loop_e < num_of_elements; loop_e++)
         {
         tmp_prob = recvd_probs(loop_n)(loop_e);
         //Clipping HACK
         perform_clipping(tmp_prob);
         this->received_probs(loop_n)(loop_e) = tmp_prob;
         alpha += tmp_prob;
         }
      assertalways(alpha!=real(0.0));
      this->received_probs(loop_n) /= alpha;
      }

   //this uses the description of the algorithm as given by
   //MacKay in Information Theory, Inference and Learning Algorithms(2003)
   //on page 560 - chapter 47.3

   //some helper variables
   int pos = 0;
   int non_zeros = 0;

   //simply set q_mxn(0)=P_n(0)=P(x_n=0) and q_mxn(1)=P_n(1)=P(x_n=1)
   for (int loop_m = 0; loop_m < this->dim_m; loop_m++)
      {
      non_zeros = this->N_m(loop_m).size();
      for (int loop_n = 0; loop_n < non_zeros; loop_n++)
         {
         pos = this->N_m(loop_m)(loop_n) - 1;//we count from zero;
         this->marginal_probs(loop_m, pos).q_mxn = this->received_probs(pos);
         this->marginal_probs(loop_m, pos).r_mxn.init(num_of_elements);
         this->marginal_probs(loop_m, pos).r_mxn = 0.0;
         }
      }

#if DEBUG>=2
   libbase::trace << " Memory Usage:\n ";
   libbase::trace << this->marginal_probs.size()
   * sizeof(sum_prod_alg_abstract<GF_q,real>::marginals) / double(1 << 20)
   << " MB" << std::endl;

   libbase::trace << std::endl << "The marginal matrix is given by:" << std::endl;
   this->print_marginal_probs(libbase::trace);
#endif

   }
Beispiel #5
0
stream_lut<real>::stream_lut(const char *filename, FILE *file, const int tau,
      const int m)
   {
   stream_lut::m = m;

   const char *s = strrchr(filename, libbase::DIR_SEPARATOR);
   const char *p = (s == NULL) ? filename : s + 1;
   this->lutname = p;

   this->lut.init(tau);

   char buf[256];
   for (int i = 0; i < tau - m; i++)
      {
      do
         {
         assertalways(fscanf(file, "%[^\n]\n", buf) == 1);
         } while (buf[0] == '#');
      int y;
      sscanf(buf, "%d", &y);
      this->lut(i) = y;
      }
   for (int t = tau - m; t < tau; t++)
      this->lut(t) = fsm::tail;
   }
Beispiel #6
0
gf_fast<m, poly> gf_fast<m, poly>::inverse() const
   {
   //0 does not have an inverse
   assertalways(0!=this->value);
   int tmp = (this->elements() - 1 - this->pow_of_alpha);
   return gf_fast<m, poly> (gf_fast<m, poly>::pow_lut[tmp]);
   }
template <class GF_q, class real> bool linear_code_utils<GF_q, real>::compute_syndrome(
      const matrix<GF_q> & parMat, const array1gfq_t & received_word_hd,
      array1gfq_t & syndrome_vec)
   {
   bool dec_success = true;
   int dim_m = parMat.size().rows();
   int length_n = parMat.size().cols();

   //check that we have compatible lengths
   assertalways(received_word_hd.size().length() == length_n);

   syndrome_vec.init(dim_m);
   GF_q tmp_val = GF_q(0);

   for (int rows = 0; rows < dim_m; rows++)
      {
      tmp_val = GF_q(0);
      for (int cols = 0; cols < length_n; cols++)
         {
         tmp_val += parMat(rows, cols) * received_word_hd(cols);
         }
      if (tmp_val != GF_q(0))
         {
         //the syndrome is non-zero
         dec_success = false;
         }
      syndrome_vec(rows) = tmp_val;

      }
   return dec_success;

   }
Beispiel #8
0
void map_dividing<libbase::vector, dbl, dbl2>::doinverse(const array1vd_t& pin,
      array1vd_t& pout) const
   {
   // Confirm input sequence to be of the correct length
   assertalways(pin.size() == This::output_block_size());
   // Create converter object and perform necessary transform
   libbase::symbol_converter<dbl,dbl2> converter(Base::M, Base::q);
   converter.aggregate_probabilities(pin, pout);
   }
Beispiel #9
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);
   }
Beispiel #10
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);
   }
Beispiel #11
0
void map_punctured<libbase::vector, dbl>::advance() const
   {
   assertalways(Base::size > 0);
   // check if matrix is already set
   if (pattern.size() == Base::size.length())
      return;
   // shorthand for puncturing matrix rate (p of P)
   const int p = libbase::matrix<int>(punc_matrix).sum();
   const int P = punc_matrix.size();
   assertalways(P > 0);
   assertalways(p > 0);
   // find out how many times the puncturing matrix fits
   const int n = Base::size.length() / P;
   assert(Base::size.length() == n * P);
   // initialise the pattern matrix
   pattern.init(Base::size.length());
   for (int t = 0, k = 0; k < n; k++)
      for (int i = 0; i < punc_matrix.size().rows(); i++)
         for (int j = 0; j < punc_matrix.size().cols(); j++, t++)
            pattern(t) = punc_matrix(i, j);
   }
void lut_interleaver<real>::transform(const libbase::vector<int>& in,
      libbase::vector<int>& out) const
   {
   const int tau = lut.size();
   assertalways(in.size() == tau);
   out.init(in.size());
   for (int t = 0; t < tau; t++)
      if (lut(t) == fsm::tail)
         out(t) = fsm::tail;
      else
         out(t) = in(lut(t));
   }
void lut_interleaver<real>::inverse(const libbase::matrix<real>& in,
      libbase::matrix<real>& out) const
   {
   const int tau = lut.size();
   const int K = in.size().cols();
   assertalways(in.size().rows() == tau);
   out.init(in.size());
   for (int t = 0; t < tau; t++)
      if (lut(t) == fsm::tail)
         for (int i = 0; i < K; i++)
            out(t, i) = real(1.0 / K);
      else
         for (int i = 0; i < K; i++)
            out(lut(t), i) = in(t, i);
   }
Beispiel #14
0
gf_fast<m, poly>& gf_fast<m, poly>::operator/=(const gf_fast<m, poly>& x)
   {
   //ensure we do not divide by 0
   assertalways(0!=x);
   //only need to do any work if we are not 0
   if (0 != this->value)
      {
      this->pow_of_alpha += (this->elements() - 1);
      this->pow_of_alpha = (this->pow_of_alpha - x.log_gf())
            % (this->elements() - 1);
      this->value = gf_fast<m, poly>::pow_lut[this->pow_of_alpha];

      }
   return *this;
   }
anneal_puncturing::anneal_puncturing(const char *fname, const int tau,
      const int s)
   {
   // store user parameters
   anneal_puncturing::tau = tau;
   anneal_puncturing::s = s;
   // initialise contribution matrix and load contribution matrix from file
   contrib.init(s, tau, tau);
   FILE *file = fopen(fname, "rb");
   if (file == NULL)
      {
      std::cerr
            << "FATAL ERROR (anneal_puncturing): Cannot open contribution file ("
            << fname << ")." << std::endl;
      exit(1);
      }
   for (int i = 0; i < tau; i++)
      for (int j = 0; j < s; j++)
         for (int k = 0; k < tau; k++)
            {
            double temp;
            if (fscanf(file, "%lf", &temp) == 0)
               assertalways(fscanf(file, "%*[^\n]\n") == 0);
            contrib(j, i, k) = temp;
            }
   fclose(file);
   // initialise the puncturing pattern as odd-even (and transmitting all data bits)
      {
      pattern.init(s, tau);
      for (int i = 0; i < s; i++)
         for (int j = 0; j < tau; j++)
            pattern(i, j) = (i == 0 || (i - 1) % 2 == j % 2);
      }
   // initialise the working vectors
   res.init(tau);
   res = 0;
   // now work the energy
      {
      for (int i = 0; i < s; i++)
         for (int j = 0; j < tau; j++)
            if (!pattern(i, j))
               energy_function(1, i, j);
      }
   // work out the system's initial energy
   E = work_energy();
   }
Beispiel #16
0
vale96int<real>::vale96int()
   {
   // set name and forced tail length
   this->lutname = "vale96int";
   this->m = 0;
   // build LUT
   const int tau = 34;
   const int a[] = {16, 29, 9, 10, 14, 6, 31, 8, 12, 22, 17, 33, 34, 23, 24,
         19, 32, 30, 13, 2, 21, 25, 26, 3, 28, 20, 27, 7, 5, 15, 4, 11, 18, 1};
   this->lut.init(tau);
   this->lut = -1;
   for (int i = 0; i < tau; i++)
      {
      const int ndx = a[i] - 1;
      // check for duplicate entries
      assertalways(this->lut(ndx) == -1);
      this->lut(ndx) = i;
      }
   }
Beispiel #17
0
void padded<real>::advance()
   {
   assertalways(otp);
   otp->advance();
   }
Beispiel #18
0
void padded<real>::seedfrom(libbase::random& r)
   {
   assertalways(otp);
   otp->seedfrom(r);
   }
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

   }