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(); }
//-------------------- 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)); } }
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); } } }
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; }
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); }
// 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 {
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; }
//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> "); }