Skip to content

Commit

Permalink
Use the generator polynomial for BCH syndrome
Browse files Browse the repository at this point in the history
As suggested by Daniel Estévez in #31, compute the
syndrome by evaluating the remainder of the received codeword r(x)
divided by the generator polynomial g(x) for alpha^j for j = 1, ..., 2t
instead of dividing r(x) by each minimal polynomial and evaluating the
resulting remainder for alpha^j for j = 1, ..., 2t.

The tradeoff is between how expensive the remainder calculation is and
how expensive it is to evaluate the remainder polynomials. One method
has more remainder calculations and shorter polynomial evaluations. The
other method has less remainder calculations and longer polynomial
evaluations. More specifically:

- Previous method: computes t polynomial divisions and evaluates 2t
  remainder polynomials, each with degree up to m (and m = 16 or 14).
- New method: computes a single polynomial division by g(x) and
  evaluates the same remainder polynomial with degree up to m*t (between
  168 and 192) 2t times.

After experimentation, it has been verified that the new method is
significantly faster!
  • Loading branch information
igorauad committed Nov 4, 2023
1 parent 37a89c2 commit 4499c1b
Showing 1 changed file with 4 additions and 14 deletions.
18 changes: 4 additions & 14 deletions lib/bch.cc
Original file line number Diff line number Diff line change
Expand Up @@ -245,21 +245,11 @@ template <typename T, typename P>
std::vector<T> bch_codec<T, P>::syndrome(u8_cptr_t codeword) const
{
assert_byte_aligned_n_k(m_n, m_k);
const auto parity_poly = gf2_poly_rem(codeword, m_n_bytes, m_g, m_gen_poly_rem_lut);
const auto parity_poly_gf2m = gf2m_poly(m_gf, parity_poly);
std::vector<T> syndrome_vec;
std::map<int, gf2_poly<T>> bi_map;
for (int i = 1; i <= (2 * m_t); i++) {
// See the notes in the above (alternative) syndrome implementation. The
// difference here is that the remainder computation to obtain b_i(x) is based on
// LUTs instead of manual bit shifts and XORs for each input bit.
if (m_conjugate_map[i] == 0) // new b_i(x)
bi_map.emplace(
i,
gf2_poly_rem(codeword, m_n_bytes, m_min_poly[i], m_min_poly_rem_lut[i]));
const int bi_idx = (m_conjugate_map[i] == 0) ? i : m_conjugate_map[i];
const auto& bi = bi_map.at(bi_idx);
const auto bi_gf2m = gf2m_poly(m_gf, bi);
syndrome_vec.push_back(bi_gf2m.eval_by_exp(i));
}
for (int i = 1; i <= (2 * m_t); i++)
syndrome_vec.push_back(parity_poly_gf2m.eval_by_exp(i));
return syndrome_vec;
}

Expand Down

0 comments on commit 4499c1b

Please sign in to comment.