예제 #1
0
Hamming_Code::Hamming_Code(int m)
{
    n = pow2i(m) - 1;
    k = pow2i(m) - m - 1;
    H.set_size(n - k, n);
    G.set_size(k, n);
    generate_H(); // generate_H must be run before generate_G
    generate_G();
}
예제 #2
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));
  }
}
예제 #3
0
void Hamming_Code::generate_H(void)
{
    int i, j, NextPos;
    char NotUsed;
    bvec temp;
    ivec indexes(n);
    indexes.zeros();

    for (i = 1; i <= n - k; i++) {
        indexes(i - 1) = pow2i(n - k - i);
    }
    NextPos = n - k;
    for (i = 1; i <= n; i++) {
        NotUsed = 1;
        for (j = 0; j < n; j++)
            if (i == indexes(j)) {
                NotUsed = 0;
            }
        if (NotUsed) {
            indexes(NextPos) = i;
            NextPos = NextPos + 1;
        }
    }

    for (i = 0; i < n; i++) {
        temp = dec2bin(n - k, indexes(i)); //<-CHECK THIS OUT!!!!
        for (j = 0; j < (n - k); j++) {
            H(j, i) = temp(j);
        }
    }
}
예제 #4
0
vec spectrum(const vec &v, const vec &w, int noverlap)
{
  int nfft = w.size();
  it_assert_debug(pow2i(levels2bits(nfft)) == nfft,
                  "The window size must be a power of two in spectrum()!");

  vec P(nfft / 2 + 1), wd(nfft);

  P = 0.0;
  double w_energy = energy(w);

  if (nfft > v.size()) {
    P = sqr(abs(fft(to_cvec(elem_mult(zero_pad(v, nfft), w)))(0, nfft / 2)));
    P /= w_energy;
  }
  else {
    int k = (v.size() - noverlap) / (nfft - noverlap), idx = 0;
    for (int i = 0; i < k; i++) {
      wd = elem_mult(v(idx, idx + nfft - 1), w);
      P += sqr(abs(fft(to_cvec(wd))(0, nfft / 2)));
      idx += nfft - noverlap;
    }
    P /= k * w_energy;
  }

  P.set_size(nfft / 2 + 1, true);
  return P;
}
예제 #5
0
void printNumDetail(const char *binResult)
{
    char *sign = binResult[0] == '0' ? "+" : "-";
    char exponent[9];
    char mantisa[24];
    memset(exponent, '\0', sizeof(exponent));
    memset(mantisa, '\0', sizeof(mantisa));
    strncpy(exponent, binResult + 1, 8);
    strncpy(mantisa, binResult + 9, 23);
    int expResult = b2dec(exponent);
    float mantisaResult = b2f(mantisa);
    printf(
        "sign: %s\nexponent: %s --> %d [%d - 127 = %d]\nmantisa: %s --> %f\n",
        sign, exponent, (expResult - 127), expResult, expResult - 127,
        mantisa, mantisaResult);
    float floatNum = pow2i(expResult - 127) * mantisaResult;
    floatNum = strcmp(sign, "+") == 0 ? floatNum : floatNum * (-1.0);
    printf("Float Format: %s 2^%d x %f = %d * %f = %f\n", sign, expResult - 127,
           mantisaResult, pow2i(expResult - 127), mantisaResult, floatNum);
}
예제 #6
0
// calculates metrics for all codewords (2^n of them) in natural order
void Convolutional_Code::calc_metric(const vec &rx_codeword,
                                     vec &delta_metrics)
{
  int no_outputs = pow2i(n), no_loop = pow2i(n - 1), mask = no_outputs - 1,
                                       temp;
  delta_metrics.set_size(no_outputs, false);

  if (no_outputs <= no_states) {
    for (int i = 0; i < no_loop; i++) { // all input possibilities
      delta_metrics(i) = 0;
      temp = i;
      for (int j = n - 1; j >= 0; j--) {
        if (temp & 1)
          delta_metrics(i) += rx_codeword(j);
        else
          delta_metrics(i) -= rx_codeword(j);
        temp >>= 1;
      }
      delta_metrics(i ^ mask) = -delta_metrics(i); // the inverse codeword
    }
  }
  else {
예제 #7
0
int b2dec(const char *bin)
{
    int len = strlen(bin);
    int sum = 0;
    int m = 0;
    int intValue = 0;

    for (int i = len - 1; i >= 0; i--)
    {
        intValue = bin[i] - '0';
        m = intValue * pow2i(7 - i);
        sum = sum + m;
        /*
         *printf("i = %d, power2i(7-i) = %d, intValue = %d, m = %d, sum = %d \n", i, pow2i(7-i), intValue, m, sum);
         */
    }

    return sum;
}
예제 #8
0
//Correlation
void xcorr(const cvec &x, const cvec &y, cvec &out, const int max_lag, const std::string scaleopt, bool autoflag)
{
  int N = std::max(x.length(), y.length());

  //Compute the FFT size as the "next power of 2" of the input vector's length (max)
  int b = ceil_i(::log2(2.0 * N - 1));
  int fftsize = pow2i(b);

  int end = fftsize - 1;

  cvec temp2;
  if (autoflag == true) {
    //Take FFT of input vector
    cvec X = fft(zero_pad(x, fftsize));

    //Compute the abs(X).^2 and take the inverse FFT.
    temp2 = ifft(elem_mult(X, conj(X)));
  }
  else {
    //Take FFT of input vectors
    cvec X = fft(zero_pad(x, fftsize));
    cvec Y = fft(zero_pad(y, fftsize));

    //Compute the crosscorrelation
    temp2 = ifft(elem_mult(X, conj(Y)));
  }

  // Compute the total number of lags to keep. We truncate the maximum number of lags to N-1.
  int maxlag;
  if ((max_lag == -1) || (max_lag >= N))
    maxlag = N - 1;
  else
    maxlag = max_lag;


  //Move negative lags to the beginning of the vector. Drop extra values from the FFT/IFFt
  if (maxlag == 0) {
    out.set_size(1, false);
    out = temp2(0);
  }
  else
    out = concat(temp2(end - maxlag + 1, end), temp2(0, maxlag));


  //Scale data
  if (scaleopt == "biased")
    //out = out / static_cast<double_complex>(N);
    out = out / static_cast<std::complex<double> >(N);
  else if (scaleopt == "unbiased") {
    //Total lag vector
    vec lags = linspace(-maxlag, maxlag, 2 * maxlag + 1);
    cvec scale = to_cvec(static_cast<double>(N) - abs(lags));
    out /= scale;
  }
  else if (scaleopt == "coeff") {
    if (autoflag == true) // Normalize by Rxx(0)
      out /= out(maxlag);
    else { //Normalize by sqrt(Rxx(0)*Ryy(0))
      double rxx0 = sum(abs(elem_mult(x, x)));
      double ryy0 = sum(abs(elem_mult(y, y)));
      out /= std::sqrt(rxx0 * ryy0);
    }
  }
  else if (scaleopt == "none") {}
  else
    it_warning("Unknow scaling option in XCORR, defaulting to <none> ");

}