void Packet_Generator::set_parameters(const int Packet_size, const unsigned long int Max_packets)
{
  it_assert(Packet_size > 0, "Packet_Generator::set_parameters(): ");
  packet_size = Packet_size;
  max_packets = Max_packets;
  id = 0;
}
Beispiel #2
0
void CRC_Code::set_generator(const bvec &poly)
{
  //it_assert(poly(0) == 1 && poly(poly.size()-1) == 1, "CRC_Code::set_polynomial: not a valid polynomial");
  it_assert(poly(0) == 1, "CRC_Code::set_polynomial: not a valid polynomial");
  polynomial = poly;
  no_parity = polynomial.size() - 1;
}
Beispiel #3
0
// m=m-m*v*v'
void sub_m_v_vT(mat &m, const vec &v)
{
  vec v2(m.rows());
  double tmp, *v2p;
  const double *vp;
  int i, j;

  it_assert(v.size() == m.cols(), "sub_m_v_vT()");

  v2p = v2._data();
  for (i = 0; i < m.rows(); i++) {
    tmp = 0.0;
    vp = v._data();
    for (j = 0; j < m.cols(); j++)
      tmp += *(vp++) * m._elem(i, j);
    *(v2p++) = tmp;
  }

  v2p = v2._data();
  for (i = 0; i < m.rows(); i++) {
    vp = v._data();
    for (j = 0; j < m.cols(); j++)
      m._elem(i, j) -= *v2p * *(vp++);
    v2p++;
  }
}
Sink::Sink(const unsigned long int Max_packets)
{
  it_assert(Max_packets > 0, "Sink::Sink(): ");
  max_packets = Max_packets;
  Ncp = 0;
  Nbytes = 0;
  packet_input.forward(this, &Sink::handle_packet_input);
  start_time = Event_Queue::now();
}
void Poisson_Packet_Generator::set_parameters(const double Avg_bit_rate,
    const int Packet_size,
    const unsigned long int Max_packets)
{
  Packet_Generator::set_parameters(Packet_size, Max_packets);
  it_assert(Avg_bit_rate > 0.0, "Packet_Generator::set_parameters(): ");
  avg_bit_rate = Avg_bit_rate;
  avg_delta_t = 8.0 * get_packet_size() / avg_bit_rate;
  ee.setup(1.0);
}
Array1D<T> zero_pad(const Array1D<T>& v, int n)
{
    it_assert(n>=v.size(), "zero_pad() cannot shrink the vector!");
    Array1D<T> v2(n);
    v2.set_subvector(0, v.size()-1, v);
    if (n > v.size())
	v2.set_subvector(v.size(), n-1, T(0));

    return v2;
}
Beispiel #7
0
void xcorr_old(const vec &x, const vec &y, vec &out, const int max_lag, const std::string scaleopt)
{
  int m, n;
  double s_plus, s_minus, M_double, coeff_scale = 0.0;
  int M, N;

  M = x.size();
  M = std::max(x.size(), y.size());
  M_double = double(M);

  if (max_lag == -1) {
    N = std::max(x.size(), y.size());
  }
  else {
    N = max_lag + 1;
  }

  out.set_size(2*N - 1, false);

  it_assert(N <= std::max(x.size(), y.size()), "max_lag cannot be as large as, or larger than, the maximum length of x and y.");

  if (scaleopt == "coeff") {
    coeff_scale = std::sqrt(energy(x)) * std::sqrt(energy(y));
  }

  for (m = 0; m < N; m++) {
    s_plus = 0;
    s_minus = 0;

    for (n = 0;n < M - m;n++) {
      s_minus += index_zero_pad(x, n) * index_zero_pad(y, n + m);
      s_plus += index_zero_pad(x, n + m) * index_zero_pad(y, n);
    }

    if (scaleopt == "none") {
      out(N + m - 1) = s_plus;
      out(N - m - 1) = s_minus;
    }
    else if (scaleopt == "biased") {
      out(N + m - 1) = s_plus / M_double;
      out(N - m - 1) = s_minus / M_double;
    }
    else if (scaleopt == "unbiased") {
      out(N + m - 1) = s_plus / double(M - m);
      out(N - m - 1) = s_minus / double(M - m);
    }
    else if (scaleopt == "coeff") {
      out(N + m - 1) = s_plus / coeff_scale;
      out(N - m - 1) = s_minus / coeff_scale;
    }
    else
      it_error("Incorrect scaleopt specified.");
  }
}
void Sink::handle_packet_input(Packet *P)
{
  it_assert(P != NULL, "Sink::handle_packet_input(): ");
  Ncp++;
  Nbytes += (P->bit_size() / 8);
  delete P;
  if (Ncp >= max_packets) {
    std::cout << "Time = " << Event_Queue::now() << ", Sink : " << std::endl;
    std::cout << "Simulation stopped because : Ncp > max_packets" << std::endl;
    Event_Queue::stop();
  }
}
Array1D<T> cross(const Array1D<T>& v1, const Array1D<T>& v2)
{
    it_assert( v1.size() == 3 && v2.size() == 3, "cross: vectors should be of size 3");

    Array1D<T> r(3);

    r(0) = v1(1) * v2(2) - v1(2) * v2(1);
    r(1) = v1(2) * v2(0) - v1(0) * v2(2);
    r(2) = v1(0) * v2(1) - v1(1) * v2(0);
    
    return r;
}
Beispiel #10
0
double cheb(int n, double x)
{
  it_assert((n >= 0), "cheb(): need a non-negative order n!");

  if (x < 1.0 && x > -1.0) {
    return std::cos(n * std::acos(x));
  }
  else if (x <= -1) {
    return (is_even(n) ? std::cosh(n * ::acosh(-x))
            : -std::cosh(n * ::acosh(-x)));
  }
  return std::cosh(n * ::acosh(x));
}
Beispiel #11
0
void BLERC::count(const bvec &in1, const bvec &in2)
{
  it_assert(setup_done == true,
            "BLERC::count(): Block size has to be setup before counting errors.");
  int min_input_length = std::min(in1.length(), in2.length());
  it_assert(blocksize <= min_input_length,
            "BLERC::count(): Block size must not be longer than input vectors.");

  for (int i = 0; i < (min_input_length / blocksize); i++) {
    CORR = true;
    for (int j = 0; j < blocksize; j++) {
      if (in1(i * blocksize + j) != in2(i * blocksize + j)) {
        CORR = false;
        break;
      }
    }
    if (CORR) {
      corrects++;
    }
    else {
      errors++;
    }
  }
}
Beispiel #12
0
void CRC_Code::set_code(const std::string &code)
{
  bvec poly;
  for (int i = 0; i < 18;i++) {
    if (crccode[i][0] == code)
      poly = bvec(crccode[i][1]);
  }

  if ((code == "WCDMA-8") || (code == "WCDMA-12") || (code == "WCDMA-16") || (code == "WCDMA-24")) {
    reverse_parity = true;
  }

  it_assert(poly.size() > 0, "This CRC code doesn't exist in the tables");
  set_generator(poly);
}
Beispiel #13
0
//-------------------- Reed-Solomon ----------------------------
//A Reed-Solomon code is a q^m-ary BCH code of length n = pow(q,m)-1.
//k = pow(q,m)-1-t. This class works for q==2.
Reed_Solomon::Reed_Solomon(int in_m, int in_t, bool sys, int in_b):
  m(in_m), t(in_t), b(in_b), systematic(sys)
{
  n = pow2i(m) - 1;
  k = pow2i(m) - 1 - 2 * t;
  q = pow2i(m);
  it_assert( (b >= 0) && (b < n), "Reed_Solomon::Reed_Solomon: narrow-sense parameter restricted to 0 <= b <= n.");
  GFX x(q, (char *)"-1 0");
  ivec alphapow(1);
  g.set(q, (char *)"0");
  for (int i = 1; i <= 2 * t; i++) {
    alphapow(0) = b + i - 1;
    g *= (x - GFX(q, alphapow));
  }
}
Beispiel #14
0
Datei: stc.cpp Projekt: nvmd/itpp
void STC::Hassibi_block_code(void)
/* This function generates the A and B matrices needed for Space-Time block codes
 * generation following Hassibi's approach:
 * S = sum_{q=1}^symb_block (A_q alpha_q + jB_q beta_q),
 * where s_q = alpha_q+jbeta_q is the symbol after modulation
 * each A_q and B_q matrix has dimension TxM
 * different A_q and B_q matrices are stacked one below the other, e.g.
 * [A_1;A_2;...;A_Q]

 * input: code_name - code name whose generator matrices are to be generated
 *        const_size - constellation size (used in Damen code)
 * outputs: symb_block - number of symbols per block
 *         A, B - generator matrices
 * inputs/outputs: for some codes these are inputs for others they are
 * predefined, so they are outputs only
 *               em_antennas - number of emission antenna
 *               channel_uses - channel uses
 */
{
    if (code_name=="V-BLAST_MxN")//classical V-BLAST
    {
    	it_assert(channel_uses > 0, "Channel uses should be strictly positive");
    	it_assert(em_antenna > 0, "Number of emission antenna should be strictly positive");
        symb_block = channel_uses*em_antenna;//number of symbols/block
        A.set_size(symb_block*channel_uses, em_antenna);
        A.zeros();
        itpp::mat temp(channel_uses, em_antenna);
        temp.zeros();
        register int tau,m;
        for (tau=0; tau<channel_uses; tau++)
        {
            for (m=0; m<em_antenna; m++)
            {
                temp(tau,m) = 1;
                A.set_submatrix(symb_block*tau+channel_uses*m, 0, itpp::to_cmat(temp));
                temp(tau,m) = 0;
            }
        }
        B = A;
    }
    else if (code_name=="imp_V-BLAST_MxN")//improved V-BLAST (code (31) in Hassibi's paper)
    {
    	it_assert(em_antenna > 0, "Number of emission antenna should be strictly positive");
    	it_assert(channel_uses == em_antenna, "Channel uses and the number of emission antenna must be equal");
        symb_block = channel_uses*em_antenna;//number of symbols/block
        std::complex<double> j(0,1);
        itpp::cmat D = itpp::diag(exp(j*(2*itpp::pi/em_antenna)*
        		itpp::linspace(0, em_antenna-1, em_antenna)));
        itpp::mat P = itpp::diag(itpp::ones(em_antenna-1), -1);
        P(0,em_antenna-1) = 1;
        A.set_size(symb_block*channel_uses, em_antenna);
        A.zeros();
        register int k,l;
        for (k=0; k<channel_uses; k++)
        {
            for (l=0; l<em_antenna; l++)
            {
                A.set_submatrix(symb_block*k+l*channel_uses, 0,
                		diag_pow(D, k)*itpp::to_cmat(mat_pow(P, l))/
                		std::sqrt(double(em_antenna)));
            }
        }
        B = A;
    }
    else if (code_name=="Alamouti_2xN")//Alamouti's orthogonal code
    {
        em_antenna = 2;//emission antenna
        channel_uses = 2;//channel uses
        symb_block = 2;//number of symbols/block

        A = "1  0;"
            "0  1;"
            "0  1;"
        	"-1  0";//A_1; A_2
        B = "1  0;"
            "0 -1;"
            "0  1;"
            "1  0";//B_1; B_2
    }
    else if (code_name=="Switched_Alamouti_4xN")
    {
        em_antenna = 4;//emission antenna
        channel_uses = 4;//channel uses
        symb_block = 4;//number of symbols/block

        A = "1  0  0  0;"
            "0  1  0  0;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  1  0  0;"
            "-1 0  0  0;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  0  1  0;"
            "0  0  0  1;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  0  0  1;"
            "0  0  -1 0";//A_1; A_2; A_3; A_4
        A *= std::sqrt(2.0);//normalization
        B = "1  0  0  0;"
            "0  -1 0  0;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  1  0  0;"
            "1  0  0  0;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  0  1  0;"
            "0  0  0  -1;"
            "0  0  0  0;"
            "0  0  0  0;"
            "0  0  0  1;"
            "0  0  1  0";//B_1; B_2; B_3; B_4
        B *= std::sqrt(2.0);
    }
    else if (code_name=="Double_Alamouti_4xN")
    {
        em_antenna = 4;//emission antenna
        channel_uses = 2;//channel uses
        symb_block = 4;//number of symbols/block

        A = "1  0  0  0;"
            "0  1  0  0;"
            "0  0  1  0;"
            "0  0  0  1;"
            "0  1  0  0;"
            "-1 0  0  0;"
            "0  0  0  1;"
            "0  0  -1 0";//A_1; A_2; A_3; A_4
        B = "1  0  0  0;"
            "0  -1 0  0;"
            "0  0  1  0;"
            "0  0  0 -1;"
            "0  1  0  0;"
            "1  0  0  0;"
            "0  0  0  1;"
            "0  0  1  0";//B_1; B_2; B_3; B_4
    }
    else if (code_name=="Jafarkhani_4xN")//Jafarkhani's quasi-orthogonal code
    {
        em_antenna = 4;//emission antenna
        channel_uses = 4;//channel uses
        symb_block = 4;//number of symbols/block

        A = "1  0  0  0;"
            "0  1  0  0;"
            "0  0  1  0;"
            "0  0  0  1;"
            "0  1  0  0;"
            "-1 0  0  0;"
            "0  0  0  1;"
            "0  0  -1 0;"
            "0  0  1  0;"
            "0  0  0  1;"
            "-1 0  0  0;"
            "0  -1 0  0;"
            "0  0  0  1;"
            "0  0  -1 0;"
            "0  -1 0  0;"
            "1  0  0  0";//A_1; A_2; A_3; A_4
        B = "1  0  0  0;"
            "0  -1  0  0;"
            "0  0  -1  0;"
            "0  0  0  1;"
            "0  1  0  0;"
            "1  0  0  0;"
            "0  0  0  -1;"
            "0  0  -1 0;"
            "0  0  1  0;"
            "0  0  0  -1;"
            "1  0  0  0;"
            "0  -1 0  0;"
            "0  0  0  1;"
            "0  0  1  0;"
            "0  1  0  0;"
            "1  0  0  0";//B_1; B_2; B_3; B_4
    }
    else if (code_name=="Golden_2x2")//Golden code as proposed by Belfiore
    {
        em_antenna = 2;//emission antenna
        channel_uses = 2;//channel uses
        symb_block = 4;//number of symbols/block

        std::complex<double> theta((1+std::sqrt(5.0))/2,0);
        std::complex<double> theta_b((1-std::sqrt(5.0))/2,0);
        std::complex<double> j(0,1);
        std::complex<double> one(1,0);
        std::complex<double> alpha = one+j*(one-theta);
        std::complex<double> alpha_b = one+j*(one-theta_b);
        std::complex<double> gamma = j;
        A.set_size(8,2);
        A(0,0) = alpha/std::sqrt(5.0);
        A(0,1) = 0;
        A(1,0) = 0;
        A(1,1) =  alpha_b/std::sqrt(5.0);//A_1
        A(2,0) = alpha*theta/std::sqrt(5.0);
        A(2,1) = 0;
        A(3,0) = 0;
        A(3,1) = alpha_b*theta_b/std::sqrt(5.0);//A_2
        A(4,0) = 0;
        A(4,1) = gamma*alpha_b/std::sqrt(5.0);
        A(5,0) = alpha/std::sqrt(5.0);
        A(5,1) = 0;//A_3
        A(6,0) = 0;
        A(6,1) = gamma*alpha_b*theta_b/std::sqrt(5.0);
        A(7,0) = alpha*theta/std::sqrt(5.0);
        A(7,1) = 0;//A_4
        B = A;
    }
    else if (code_name=="Damen_2x2")//ST code based on number theory as proposed by Damen
    {
        em_antenna = 2;//emission antenna
        channel_uses = 2;//channel uses
        symb_block = 4;//number of symbols/block

        double lambda;
        if (const_size==4)
            lambda = 0.5;
        else if (const_size==16)
            lambda = 0.521;
        else if (const_size>=256)
            lambda = itpp::pi/4;
        else
        {
            lambda = itpp::pi/4;
            std::cout << "STC::LDcode: Warning! For " << code_name <<
            		" and const. size " << const_size << ", lambda has the "
            		"value " << lambda << std::endl;
        }
        std::complex<double> j(0,1);
        std::complex<double> phi = std::exp(j*lambda);
        std::complex<double> theta = std::exp(j*(lambda/2));
        A.set_size(8, 2);
        A(0,0) = 1/std::sqrt(2.0);
        A(0,1) = 0;
        A(1,0) = 0;
        A(1,1) = 1/std::sqrt(2.0);//A_1
        A(2,0) = phi/std::sqrt(2.0);
        A(2,1) = 0;
        A(3,0) = 0;
        A(3,1) = -phi/std::sqrt(2.0);//A_2
        A(4,0) = 0;
        A(4,1) = theta/std::sqrt(2.0);
        A(5,0) = theta/std::sqrt(2.0);
        A(5,1) = 0;//A_3
        A(6,0) = 0;
        A(6,1) = -theta*phi/std::sqrt(2.0);
        A(7,0) = theta*phi/std::sqrt(2.0);
        A(7,1) = 0;//A_4
        B = A;
    }
    else if (code_name=="34ortho_3xN")//rate 3/4 orthogonal code (mutual information 5.13 bits/channel use at rho=20 dB)
    {
        em_antenna = 3;//emission antenna
        channel_uses = 4;//channel uses
        symb_block = 3;//number of symbols/block

        A = "1 0 0;"
            "0 1 0;"
            "0 0 1;"
            "0 0 0;"
            "0 1 0;"
            "-1 0 0;"
            "0 0 0;"
            "0 0 1;"
            "0 0 1;"
            "0 0 0;"
            "-1 0 0;"
            "0 -1 0";//A_1; A_2; A_3
        A /= std::sqrt(double(4)/double(3));
        B = "1 0 0;"
            "0 -1 0;"
            "0 0 -1;"
            "0 0 0;"
            "0 1 0;"
            "1 0 0;"
            "0 0 0;"
            "0 0 -1;"
            "0 0 1;"
            "0 0 0;"
            "1 0 0;"
            "0 1 0";//B_1; B_2; B_3
        B /= std::sqrt(double(4)/double(3));
    }
    else if (code_name=="36LD_3xN")//(36) LD code with mutual info. 6.25bits/channel use at rho=20dB
    {
        em_antenna = 3;//emission antenna
        channel_uses = 4;//channel uses
        symb_block = 4;//number of symbols/block

        A.set_size(16, 3);
        A(0,0) = 1;
        A(0,1) = 0;
        A(0,2) = 0;
        A(1,0) = 1;
        A(1,1) = 1;
        A(1,2) = 0;
        A(2,0) = 0;
        A(2,1) = 0;
        A(2,2) = 1;
        A(3,0) = 0;
        A(3,1) = 0;
        A(3,2) = 0;//A_1
        A(4,0) = 0;
        A(4,1) = 1/std::sqrt(2.0);
        A(4,2) = 0;
        A(5,0) = -1/std::sqrt(2.0);
        A(5,1) = 0;
        A(5,2) = -1/std::sqrt(2.0);
        A(6,0) = 0;
        A(6,1) = 1/std::sqrt(2.0);
        A(6,2) = 0;
        A(7,0) = 1/std::sqrt(2.0);
        A(7,1) = 0;
        A(7,2) = -1/std::sqrt(2.0);//A_2
        A(8,0) = 1;
        A(8,1) = 0;
        A(8,2) = 0;
        A(9,0) = 0;
        A(9,1) = 0;
        A(9,2) = 0;
        A(10,0) = 0;
        A(10,1) = 0;
        A(10,2) = -1;
        A(11,0) = 0;
        A(11,1) = -1;
        A(11,2) = 0;//A_3
        A(12,0) = 0;
        A(12,1) = -1/std::sqrt(2.0);
        A(12,2) = 0;
        A(13,0) = 1/std::sqrt(2.0);
        A(13,1) = 0;
        A(13,2) = -1/std::sqrt(2.0);
        A(14,0) = 0;
        A(14,1) = 1/std::sqrt(2.0);
        A(14,2) = 0;
        A(15,0) = -1/std::sqrt(2.0);
        A(15,1) = 0;
        A(15,2) = -1/std::sqrt(2.0);//A_4
        B.set_size(16, 3);
        B(0,0) = 0;
        B(0,1) = -1/std::sqrt(2.0);
        B(0,2) = 0;
        B(1,0) = -1/std::sqrt(2.0);
        B(1,1) = 0;
        B(1,2) = 1/std::sqrt(2.0);
        B(2,0) = 0;
        B(2,1) = 1/std::sqrt(2.0);
        B(2,2) = 0;
        B(3,0) = 1/std::sqrt(2.0);
        B(3,1) = 0;
        B(3,2) = 1/std::sqrt(2.0);//B_1
        B(4,0) = 1/std::sqrt(2.0);
        B(4,1) = double(-1)/double(2);
        B(4,2) = 0;
        B(5,0) = double(-1)/double(2);
        B(5,1) = -1/std::sqrt(2.0);
        B(5,2) = double(-1)/double(2);
        B(6,0) = 0;
        B(6,1) = double(-1)/double(2);
        B(6,2) = 1/std::sqrt(2.0);
        B(7,0) = double(1)/double(2);
        B(7,1) = 0;
        B(7,2) = double(-1)/double(2);//B_2
        B(8,0) = 1/std::sqrt(2.0);
        B(8,1) = double(1)/double(2);
        B(8,2) = 0;
        B(9,0) = double(1)/double(2);
        B(9,1) = -1/std::sqrt(2.0);
        B(9,2) = double(1)/double(2);
        B(10,0) = 0;
        B(10,1) = double(1)/double(2);
        B(10,2) = 1/std::sqrt(2.0);
        B(11,0) = double(-1)/double(2);
        B(11,1) = 0;
        B(11,2) = double(1)/double(2);//B_3
        B(12,0) = 1;
        B(12,1) = 0;
        B(12,2) = 0;
        B(13,0) = 0;
        B(13,1) = 0;
        B(13,2) = 0;
        B(14,0) = 0;
        B(14,1) = 0;
        B(14,2) = -1;
        B(15,0) = 0;
        B(15,1) = 1;
        B(15,2) = 0;//B_4
    }
    else if (code_name=="37LD_3xN")//(37) LD code 3-antenna LD code obtained from the symetrical concatenation of 3 2-antenna orthogonal design
    {
        em_antenna = 3;//emission antenna
        channel_uses = 6;//channel uses
        symb_block = 6;//number of symbols/block

        A = "1  0  0;"
            "0  1  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  1  0;"
            "-1 0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  1  0;"
            "0  0  1;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  1;"
            "0 -1  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "1  0  0;"
            "0  0  1;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  1;"
            "-1 0  0";//A_1; A_2; A_3; A_4; A_5; A_6
        A *= std::sqrt(double(3)/double(2));
        B = "1  0  0;"
            "0  -1  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  1  0;"
            "1 0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  1  0;"
            "0  0  -1;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  1;"
            "0  1  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "1  0  0;"
            "0  0  -1;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  0;"
            "0  0  1;"
            "1  0  0";//B_1; B_2; B_3; B_4; B_5; B_6
        B *= std::sqrt(double(3)/double(2));
    }
    else if (code_name=="39LD_3xN")
    {
        em_antenna = 3;//emission antenna
        channel_uses = 6;//channel uses
        symb_block = 6;//number of symbols/block

        A.set_size(36, 3);
        A(0,0) = 1/std::sqrt(2.0);
        A(0,1) = 0;
        A(0,2) = 0;
        A(1,0) = 0;
        A(1,1) = 1/std::sqrt(2.0);
        A(1,2) = 0;
        A(2,0) = 0;
        A(2,1) = 1/std::sqrt(2.0);
        A(2,2) = 0;
        A(3,0) = 0;
        A(3,1) = 0;
        A(3,2) = 1/std::sqrt(2.0);
        A(4,0) = 1/std::sqrt(2.0);
        A(4,1) = 0;
        A(4,2) = 0;
        A(5,0) = 0;
        A(5,1) = 0;
        A(5,2) = 1/std::sqrt(2.0);//A_1
        A(6,0) = 0;
        A(6,1) = 1/std::sqrt(2.0);
        A(6,2) = 0;
        A(7,0) = -1/std::sqrt(2.0);
        A(7,1) = 0;
        A(7,2) = 0;
        A(8,0) = 0;
        A(8,1) = 0;
        A(8,2) = 1/std::sqrt(2.0);
        A(9,0) = 0;
        A(9,1) = -1/std::sqrt(2.0);
        A(9,2) = 0;
        A(10,0) = 0;
        A(10,1) = 0;
        A(10,2) = 1/std::sqrt(2.0);
        A(11,0) = -1/std::sqrt(2.0);
        A(11,1) = 0;
        A(11,2) = 0;//A_2
        A(12,0) = 1/std::sqrt(2.0);
        A(12,1) = 0;
        A(12,2) = 0;
        A(13,0) = 0;
        A(13,1) = 1/std::sqrt(2.0);
        A(13,2) = 0;
        A(14,0) = 0;
        A(14,1) = -1/(2*std::sqrt(2.0));
        A(14,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(15,0) = 0;
        A(15,1) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(15,2) = -1/(2*std::sqrt(2.0));
        A(16,0) = -1/(2*std::sqrt(2.0));
        A(16,1) = 0;
        A(16,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(17,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(17,1) = 0;
        A(17,2) = -1/(2*std::sqrt(2.0));//A_3
        A(18,0) = 0;
        A(18,1) = 1/std::sqrt(2.0);
        A(18,2) = 0;
        A(19,0) = -1/std::sqrt(2.0);
        A(19,1) = 0;
        A(19,2) = 0;
        A(20,0) = 0;
        A(20,1) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(20,2) = -1/(2*std::sqrt(2.0));
        A(21,0) = 0;
        A(21,1) = 1/(2*std::sqrt(2.0));
        A(21,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(22,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(22,1) = 0;
        A(22,2) = -1/(2*std::sqrt(2.0));
        A(23,0) = 1/(2*std::sqrt(2.0));
        A(23,1) = 0;
        A(23,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));//A_4
        A(24,0) = 1/std::sqrt(2.0);
        A(24,1) = 0;
        A(24,2) = 0;
        A(25,0) = 0;
        A(25,1) = 1/std::sqrt(2.0);
        A(25,2) = 0;
        A(26,0) = 0;
        A(26,1) = -1/(2*std::sqrt(2.0));
        A(26,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(27,0) = 0;
        A(27,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(27,2) = -1/(2*std::sqrt(2.0));
        A(28,0) = -1/(2*std::sqrt(2.0));
        A(28,1) = 0;
        A(28,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(29,0) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(29,1) = 0;
        A(29,2) = -1/(2*std::sqrt(2.0));//A_5
        A(30,0) = 0;
        A(30,1) = 1/std::sqrt(2.0);
        A(30,2) = 0;
        A(31,0) = -1/std::sqrt(2.0);
        A(31,1) = 0;
        A(31,2) = 0;
        A(32,0) = 0;
        A(32,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(32,2) = -1/(2*std::sqrt(2.0));
        A(33,0) = 0;
        A(33,1) = 1/(2*std::sqrt(2.0));
        A(33,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(34,0) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        A(34,1) = 0;
        A(34,2) = -1/(2*std::sqrt(2.0));
        A(35,0) = 1/(2*std::sqrt(2.0));
        A(35,1) = 0;
        A(35,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));//A_6
        B.set_size(36, 3);
        B(0,0) = 1/std::sqrt(2.0);
        B(0,1) = 0;
        B(0,2) = 0;
        B(1,0) = 0;
        B(1,1) = -1/std::sqrt(2.0);
        B(1,2) = 0;
        B(2,0) = 0;
        B(2,1) = 1/std::sqrt(2.0);
        B(2,2) = 0;
        B(3,0) = 0;
        B(3,1) = 0;
        B(3,2) = -1/std::sqrt(2.0);
        B(4,0) = 1/std::sqrt(2.0);
        B(4,1) = 0;
        B(4,2) = 0;
        B(5,0) = 0;
        B(5,1) = 0;
        B(5,2) = -1/std::sqrt(2.0);//B_1
        B(6,0) = 0;
        B(6,1) = 1/std::sqrt(2.0);
        B(6,2) = 0;
        B(7,0) = 1/std::sqrt(2.0);
        B(7,1) = 0;
        B(7,2) = 0;
        B(8,0) = 0;
        B(8,1) = 0;
        B(8,2) = 1/std::sqrt(2.0);
        B(9,0) = 0;
        B(9,1) = 1/std::sqrt(2.0);
        B(9,2) = 0;
        B(10,0) = 0;
        B(10,1) = 0;
        B(10,2) = 1/std::sqrt(2.0);
        B(11,0) = 1/std::sqrt(2.0);
        B(11,1) = 0;
        B(11,2) = 0;//B_2
        B(12,0) = 1/std::sqrt(2.0);
        B(12,1) = 0;
        B(12,2) = 0;
        B(13,0) = 0;
        B(13,1) = -1/std::sqrt(2.0);
        B(13,2) = 0;
        B(14,0) = 0;
        B(14,1) = -1/(2*std::sqrt(2.0));
        B(14,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(15,0) = 0;
        B(15,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(15,2) = 1/(2*std::sqrt(2.0));
        B(16,0) = -1/(2*std::sqrt(2.0));
        B(16,1) = 0;
        B(16,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(17,0) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(17,1) = 0;
        B(17,2) = 1/(2*std::sqrt(2.0));//B_3
        B(18,0) = 0;
        B(18,1) = 1/std::sqrt(2.0);
        B(18,2) = 0;
        B(19,0) = 1/std::sqrt(2.0);
        B(19,1) = 0;
        B(19,2) = 0;
        B(20,0) = 0;
        B(20,1) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(20,2) = -1/(2*std::sqrt(2.0));
        B(21,0) = 0;
        B(21,1) = -1/(2*std::sqrt(2.0));
        B(21,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(22,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(22,1) = 0;
        B(22,2) = -1/(2*std::sqrt(2.0));
        B(23,0) = -1/(2*std::sqrt(2.0));
        B(23,1) = 0;
        B(23,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));//B_4
        B(24,0) = 1/std::sqrt(2.0);
        B(24,1) = 0;
        B(24,2) = 0;
        B(25,0) = 0;
        B(25,1) = -1/std::sqrt(2.0);
        B(25,2) = 0;
        B(26,0) = 0;
        B(26,1) = -1/(2*std::sqrt(2.0));
        B(26,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(27,0) = 0;
        B(27,1) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(27,2) = 1/(2*std::sqrt(2.0));
        B(28,0) = -1/(2*std::sqrt(2.0));
        B(28,1) = 0;
        B(28,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(29,0) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(29,1) = 0;
        B(29,2) = 1/(2*std::sqrt(2.0));//B_5
        B(30,0) = 0;
        B(30,1) = 1/std::sqrt(2.0);
        B(30,2) = 0;
        B(31,0) = 1/std::sqrt(2.0);
        B(31,1) = 0;
        B(31,2) = 0;
        B(32,0) = 0;
        B(32,1) = -std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(32,2) = -1/(2*std::sqrt(2.0));
        B(33,0) = 0;
        B(33,1) = -1/(2*std::sqrt(2.0));
        B(33,2) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(34,0) = std::sqrt(3.0)/(2*std::sqrt(2.0));
        B(34,1) = 0;
        B(34,2) = -1/(2*std::sqrt(2.0));
        B(35,0) = -1/(2*std::sqrt(2.0));
        B(35,1) = 0;
        B(35,2) = -std::sqrt(3.0)/(2*std::sqrt(2.0));//B_6
    }
    else
    {
        it_assert(false, "Unknown code name.");
    }
}
Beispiel #15
0
bool Reed_Solomon::decode(const bvec &coded_bits, const ivec &erasure_positions, bvec &decoded_message, bvec &cw_isvalid)
{
  bool decoderfailure, no_dec_failure;
  int j, i, kk, l, L, foundzeros, iterations = floor_i(static_cast<double>(coded_bits.length()) / (n * m));
  bvec mbit(m * k);
  decoded_message.set_size(iterations * k * m, false);
  cw_isvalid.set_length(iterations);

  GFX rx(q, n - 1), cx(q, n - 1), mx(q, k - 1), ex(q, n - 1), S(q, 2 * t), Xi(q, 2 * t), Gamma(q), Lambda(q),
      Psiprime(q), OldLambda(q), T(q), Omega(q);
  GFX dummy(q), One(q, (char*)"0"), Omegatemp(q);
  GF delta(q), tempsum(q), rtemp(q), temp(q), Xk(q), Xkinv(q);
  ivec errorpos;

  if ( erasure_positions.length() ) {
    it_assert(max(erasure_positions) < iterations*n, "Reed_Solomon::decode: erasure position is invalid.");
  }
  
  no_dec_failure = true;
  for (i = 0; i < iterations; i++) {
    decoderfailure = false;
    //Fix the received polynomial r(x)
    for (j = 0; j < n; j++) {
      rtemp.set(q, coded_bits.mid(i * n * m + j * m, m));
      rx[j] = rtemp;
    }
    // Fix the Erasure polynomial Gamma(x)
    // and replace erased coordinates with zeros
    rtemp.set(q, -1);
    ivec alphapow = - ones_i(2);
    Gamma = One;
    for (j = 0; j < erasure_positions.length(); j++) {
      rx[erasure_positions(j)] = rtemp;
      alphapow(1) = erasure_positions(j);
      Gamma *= (One - GFX(q, alphapow));
    }
    //Fix the syndrome polynomial S(x).
    S.clear();
    for (j = 1; j <= 2 * t; j++) {
      S[j] = rx(GF(q, b + j - 1));
    }
    // calculate the modified syndrome polynomial Xi(x) = Gamma * (1+S) - 1
    Xi = Gamma * (One + S) - One;
    // Apply Berlekam-Massey algorithm
    if (Xi.get_true_degree() >= 1) { //Errors in the received word
      // Iterate to find Lambda(x), which hold all error locations
      kk = 0;
      Lambda = One;
      L = 0;
      T = GFX(q, (char*)"-1 0");
      while (kk < 2 * t) {
        kk = kk + 1;
        tempsum = GF(q, -1);
        for (l = 1; l <= L; l++) {
          tempsum += Lambda[l] * Xi[kk - l];
        }
        delta = Xi[kk] - tempsum;
        if (delta != GF(q, -1)) {
          OldLambda = Lambda;
          Lambda -= delta * T;
          if (2 * L < kk) {
            L = kk - L;
            T = OldLambda / delta;
          }
        }
        T = GFX(q, (char*)"-1 0") * T;
      }
      // Find the zeros to Lambda(x)
      errorpos.set_size(Lambda.get_true_degree());
      foundzeros = 0;
      for (j = q - 2; j >= 0; j--) {
        if (Lambda(GF(q, j)) == GF(q, -1)) {
          errorpos(foundzeros) = (n - j) % n;
          foundzeros += 1;
          if (foundzeros >= Lambda.get_true_degree()) {
            break;
          }
        }
      }
      if (foundzeros != Lambda.get_true_degree()) {
        decoderfailure = true;
      }
      else { // Forney algorithm...
        //Compute Omega(x) using the key equation for RS-decoding
        Omega.set_degree(2 * t);
        Omegatemp = Lambda * (One + Xi);
        for (j = 0; j <= 2 * t; j++) {
          Omega[j] = Omegatemp[j];
        }
        //Find the error/erasure magnitude polynomial by treating them the same
        Psiprime = formal_derivate(Lambda*Gamma);
        errorpos = concat(errorpos, erasure_positions);
        ex.clear();
        for (j = 0; j < errorpos.length(); j++) {
          Xk = GF(q, errorpos(j));
          Xkinv = GF(q, 0) / Xk;
          // we calculate ex = - error polynomial, in order to avoid the 
          // subtraction when recunstructing the corrected codeword
          ex[errorpos(j)] = (Xk * Omega(Xkinv)) / Psiprime(Xkinv);
          if (b != 1) { // non-narrow-sense code needs corrected error magnitudes
            int correction_exp = ( errorpos(j)*(1-b) ) % n;
            ex[errorpos(j)] *= GF(q, correction_exp + ( (correction_exp < 0) ? n : 0 ));
          }
        }
        //Reconstruct the corrected codeword.
        // instead of subtracting the error/erasures, we calculated 
        // the negative error with 'ex' above
        cx = rx + ex;
        //Code word validation
        S.clear();
        for (j = 1; j <= 2 * t; j++) {
          S[j] = cx(GF(q, b + j - 1));
        }
        if (S.get_true_degree() >= 1) {
          decoderfailure = true;
        }
      }
    }
    else {
      cx = rx;
      decoderfailure = false;
    }
    //Find the message polynomial
    mbit.clear();
    if (decoderfailure == false) {
      if (cx.get_true_degree() >= 1) { // A nonzero codeword was transmitted
        if (systematic) {
          for (j = 0; j < k; j++) {
            mx[j] = cx[j];
          }
        }
        else {
          mx = divgfx(cx, g);
        }
        for (j = 0; j <= mx.get_true_degree(); j++) {
          mbit.replace_mid(j * m, mx[j].get_vectorspace());
        }
      }
    }
    else { //Decoder failure.
      // for a systematic code it is better to extract the undecoded message
      // from the received code word, i.e. obtaining a bit error
      // prob. p_b << 1/2, than setting all-zero (p_b = 1/2)
      if (systematic) {
        mbit = coded_bits.mid(i * n * m, k * m);
      }
      else {
        mbit = zeros_b(k);
      }
      no_dec_failure = false;
    }
    decoded_message.replace_mid(i * m * k, mbit);
    cw_isvalid(i) = (!decoderfailure);
  }
  return no_dec_failure;
}