void Hamming_Code::decode(const bvec &coded_bits, bvec &decoded_bits) { int length = coded_bits.length(); int Itterations = floor_i(static_cast<double>(length) / n); ivec Hindexes(n); bvec temp(n - k); bvec coded(n), syndrome(n - k); int isynd, errorpos = 0; int i, j; decoded_bits.set_size(Itterations*k, false); for (i = 0; i < n; i++) { for (j = 0; j < n - k; j++) temp(j) = H(j, i); Hindexes(i) = bin2dec(temp); } //Decode all codewords for (i = 0; i < Itterations; i++) { coded = coded_bits.mid(i * n, n); syndrome = H * coded; isynd = bin2dec(syndrome); if (isynd != 0) { for (j = 0; j < n; j++) if (Hindexes(j) == isynd) { errorpos = j; }; coded(errorpos) += 1; } decoded_bits.replace_mid(k*i, coded.right(k)); } }
bvec Extended_Golay::decode(const bvec &coded_bits) { int no_bits = coded_bits.length(); int no_blocks = (int)floor((double)no_bits/24); bvec output(12*no_blocks); int i; int j; bvec S(12),BS(12),r(12),temp(12),e(24),c(24); bmat eyetemp = eye_b(12); for (i=0; i<no_blocks; i++) { r = coded_bits.mid(i*24,24); // Step 1. Compute S=G*r. S = G*r; // Step 2. w(S)<=3. e=(S,0). Goto 8. if( weight(S) <= 3 ) { e = concat(S, zeros_b(12)); goto Step8; } // Step 3. w(S+Ii)<=2. e=(S+Ii,yi). Goto 8. for (j=0; j<12; j++) { temp = S + B.get_col(j); if ( weight(temp) <=2 ) { e = concat(temp, eyetemp.get_row(j)); goto Step8; } } // STEP 4. Compute B*S BS = B*S; // Step 5. w(B*S)<=3. e=(0,BS). Goto8. if ( weight(BS) <=3 ) { e = concat(zeros_b(12), BS); goto Step8; } // Step 6. w(BS+Ri)<=2. e=(xi,BS+Ri). Goto 8. for (j=0; j<12; j++) { temp = BS + B.get_row(j); if ( weight(temp) <=2 ) { e = concat(eyetemp.get_row(j), temp); goto Step8; } } // Step 7. Uncorrectable erreor pattern. Choose the first 12 bits. e = zeros_b(24); goto Step8; Step8: // Step 8. c=r+e. STOP c = r + e; output.replace_mid(i*12, c.left(12)); } return output; }
void BERC::estimate_delay(const bvec &in1, const bvec &in2, int mindelay, int maxdelay) { int num, start1, start2; int min_input_length = std::min(in1.length(), in2.length()); int bestdelay = mindelay; double correlation; double bestcorr = 0; for (int i = mindelay; i < maxdelay; i++) { num = min_input_length - std::abs(i) - ignorefirst - ignorelast; start1 = (i < 0) ? -i : 0; start2 = (i > 0) ? i : 0; correlation = fabs(sum(to_vec(elem_mult(in1.mid(start1, num), in2.mid(start2, num))))); if (correlation > bestcorr) { bestdelay = i; bestcorr = correlation; } } delay = bestdelay; }
bvec Extended_Golay::encode(const bvec &uncoded_bits) { int no_bits = uncoded_bits.length(); int no_blocks = (int)floor((double)no_bits/12); bvec output(24*no_blocks); int i; for (i=0; i<no_blocks; i++) output.replace_mid(24*i, uncoded_bits.mid(i*12,12)*G); return output; }
void Hamming_Code::encode(const bvec &uncoded_bits, bvec &coded_bits) { int length = uncoded_bits.length(); int Itterations = floor_i(static_cast<double>(length) / k); bmat Gt = G.T(); int i; coded_bits.set_size(Itterations * n, false); //Code all codewords for (i = 0; i < Itterations; i++) coded_bits.replace_mid(n*i, Gt * uncoded_bits.mid(i*k, k)); }
void Reed_Solomon::encode(const bvec &uncoded_bits, bvec &coded_bits) { int i, j, iterations = floor_i(static_cast<double>(uncoded_bits.length()) / (k * m)); GFX mx(q, k), cx(q, n); GFX r(n + 1, n - k); GFX uncoded_shifted(n + 1, n); GF mpow; bvec mbit(k * m), cbit(m); coded_bits.set_size(iterations * n * m, false); if (systematic) for (i = 0; i < n - k; i++) uncoded_shifted[i] = GF(n + 1, -1); for (i = 0; i < iterations; i++) { //Fix the message polynom m(x). for (j = 0; j < k; j++) { mpow.set(q, uncoded_bits.mid((i * m * k) + (j * m), m)); mx[j] = mpow; if (systematic) { cx[j] = mx[j]; uncoded_shifted[j + n - k] = mx[j]; } } //Fix the outputbits cbit. if (systematic) { r = modgfx(uncoded_shifted, g); for (j = k; j < n; j++) { cx[j] = r[j - k]; } } else { cx = g * mx; } for (j = 0; j < n; j++) { cbit = cx[j].get_vectorspace(); coded_bits.replace_mid((i * n * m) + (j * m), cbit); } } }
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; }