From 61b7c19e688ffb67795db8f5670607006af0d6cb Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Thu, 20 Sep 2018 20:50:06 +0200 Subject: [PATCH] added Artin Schreier's imap acceleration --- bose_chaudhuri_hocquenghem_decoder.hh | 4 ++-- reed_solomon_decoder.hh | 4 ++-- reed_solomon_error_correction.hh | 34 +++++++++++++++++++++------ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/bose_chaudhuri_hocquenghem_decoder.hh b/bose_chaudhuri_hocquenghem_decoder.hh index 9c8e9f7..9f24997 100644 --- a/bose_chaudhuri_hocquenghem_decoder.hh +++ b/bose_chaudhuri_hocquenghem_decoder.hh @@ -19,7 +19,7 @@ public: typedef typename GF::ValueType ValueType; typedef typename GF::IndexType IndexType; static const int N = GF::N, NP = N - K; - BoseChaudhuriHocquenghemDecoder() {} + ReedSolomonErrorCorrection algorithm; int compute_syndromes(ValueType *code, ValueType *syndromes) { // $syndromes_i = code(pe^{FCR+i})$ @@ -49,7 +49,7 @@ public: return 0; IndexType locations[NR]; ValueType magnitudes[NR]; - int count = ReedSolomonErrorCorrection::algorithm(syndromes, locations, magnitudes, erasures, erasures_count); + int count = algorithm(syndromes, locations, magnitudes, erasures, erasures_count); if (count <= 0) return count; for (int i = 0; i < count; ++i) diff --git a/reed_solomon_decoder.hh b/reed_solomon_decoder.hh index ca8392b..fbbde5c 100644 --- a/reed_solomon_decoder.hh +++ b/reed_solomon_decoder.hh @@ -19,7 +19,7 @@ public: typedef typename GF::ValueType ValueType; typedef typename GF::IndexType IndexType; static const int N = GF::N, K = N - NR; - ReedSolomonDecoder() {} + ReedSolomonErrorCorrection algorithm; int compute_syndromes(ValueType *code, ValueType *syndromes) { // $syndromes_i = code(pe^{FCR+i})$ @@ -49,7 +49,7 @@ public: return 0; IndexType locations[NR]; ValueType magnitudes[NR]; - int count = ReedSolomonErrorCorrection::algorithm(syndromes, locations, magnitudes, erasures, erasures_count); + int count = algorithm(syndromes, locations, magnitudes, erasures, erasures_count); if (count <= 0) return count; for (int i = 0; i < count; ++i) diff --git a/reed_solomon_error_correction.hh b/reed_solomon_error_correction.hh index 37b9e22..ade3b26 100644 --- a/reed_solomon_error_correction.hh +++ b/reed_solomon_error_correction.hh @@ -35,30 +35,49 @@ struct Chien }; template -struct FindLocations +struct LocationFinder { typedef typename GF::value_type value_type; typedef typename GF::ValueType ValueType; typedef typename GF::IndexType IndexType; - static int search(ValueType *locator, int locator_degree, IndexType *locations) + static const int Q = GF::Q, N = GF::N; + ValueType Artin_Schreier_imap[Q]; + LocationFinder() + { + for (int i = 0; i < Q; ++i) + Artin_Schreier_imap[i] = ValueType(0); + for (int i = 2; i < N; i += 2) { + ValueType x(i); + ValueType xxx = x * x + x; + if (xxx == ValueType(N)) + continue; + assert(xxx.v); + assert(!Artin_Schreier_imap[xxx.v].v); + Artin_Schreier_imap[xxx.v] = x; + } + } + ValueType imap(ValueType a) { + assert(a.v <= a.N); + assert(a.v); + return Artin_Schreier_imap[a.v]; + } + int operator()(ValueType *locator, int locator_degree, IndexType *locations) { if (locator_degree == 1) { locations[0] = (index(locator[0]) / index(locator[1])) / IndexType(1); return 1; } -#if 0 if (locator_degree == 2) { if (!locator[1] || !locator[0]) return 0; ValueType a(locator[2]), b(locator[1]), c(locator[0]); - ValueType ba(b/a), R(Artin_Schreier_imap(a*c/(b*b))); + ValueType ba(b/a), R(imap(a*c/(b*b))); if (!R) return 0; locations[0] = index(ba * R) / IndexType(1); locations[1] = index(ba * R + ba) / IndexType(1); return 2; } -#endif return Chien::search(locator, locator_degree, locations); } }; @@ -171,7 +190,8 @@ struct ReedSolomonErrorCorrection typedef typename GF::ValueType ValueType; typedef typename GF::IndexType IndexType; static const int N = GF::N, K = N - NR; - static int algorithm(ValueType *syndromes, IndexType *locations, ValueType *magnitudes, IndexType *erasures = 0, int erasures_count = 0) + RS::LocationFinder search; + int operator()(ValueType *syndromes, IndexType *locations, ValueType *magnitudes, IndexType *erasures = 0, int erasures_count = 0) { assert(0 <= erasures_count && erasures_count <= NR); ValueType locator[NR+1]; @@ -193,7 +213,7 @@ struct ReedSolomonErrorCorrection while (!locator[locator_degree]) if (--locator_degree < 0) return -1; - int count = RS::FindLocations::search(locator, locator_degree, locations); + int count = search(locator, locator_degree, locations); if (count < locator_degree) return -1; ValueType evaluator[NR];