mirror of
https://github.com/aicodix/code.git
synced 2026-04-27 14:30:36 +00:00
added Reed Solomon error correction
lifted from my FEC project: https://github.com/xdsopl/FEC
This commit is contained in:
parent
dab95db1bc
commit
01db8f516e
10 changed files with 846 additions and 1 deletions
74
reed_solomon_decoder.hh
Normal file
74
reed_solomon_decoder.hh
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Reed Solomon Decoder
|
||||
|
||||
Copyright 2018 Ahmet Inan <inan@aicodix.de>
|
||||
*/
|
||||
|
||||
#ifndef REED_SOLOMON_DECODER_HH
|
||||
#define REED_SOLOMON_DECODER_HH
|
||||
|
||||
#include "reed_solomon_error_correction.hh"
|
||||
|
||||
namespace CODE {
|
||||
|
||||
template <int NR, int FCR, typename GF>
|
||||
class ReedSolomonDecoder
|
||||
{
|
||||
public:
|
||||
typedef typename GF::value_type value_type;
|
||||
typedef typename GF::ValueType ValueType;
|
||||
typedef typename GF::IndexType IndexType;
|
||||
static const int N = GF::N, K = N - NR;
|
||||
ReedSolomonDecoder() {}
|
||||
int compute_syndromes(ValueType *code, ValueType *syndromes)
|
||||
{
|
||||
// $syndromes_i = code(pe^{FCR+i})$
|
||||
for (int i = 0; i < NR; ++i)
|
||||
syndromes[i] = code[0];
|
||||
for (int j = 1; j < N; ++j) {
|
||||
IndexType root(FCR), pe(1);
|
||||
for (int i = 0; i < NR; ++i) {
|
||||
syndromes[i] = fma(root, syndromes[i], code[j]);
|
||||
root *= pe;
|
||||
}
|
||||
}
|
||||
int nonzero = 0;
|
||||
for (int i = 0; i < NR; ++i)
|
||||
nonzero += !!syndromes[i];
|
||||
return nonzero;
|
||||
}
|
||||
int operator()(ValueType *code, IndexType *erasures = 0, int erasures_count = 0)
|
||||
{
|
||||
assert(0 <= erasures_count && erasures_count <= NR);
|
||||
if (0) {
|
||||
for (int i = 0; i < erasures_count; ++i)
|
||||
code[(int)erasures[i]] = ValueType(0);
|
||||
}
|
||||
ValueType syndromes[NR];
|
||||
if (!compute_syndromes(code, syndromes))
|
||||
return 0;
|
||||
IndexType locations[NR];
|
||||
ValueType magnitudes[NR];
|
||||
int count = ReedSolomonErrorCorrection<NR, FCR, GF>::algorithm(syndromes, locations, magnitudes, erasures, erasures_count);
|
||||
if (count <= 0)
|
||||
return count;
|
||||
for (int i = 0; i < count; ++i)
|
||||
code[(int)locations[i]] += magnitudes[i];
|
||||
int corrections_count = 0;
|
||||
for (int i = 0; i < count; ++i)
|
||||
corrections_count += !!magnitudes[i];
|
||||
return corrections_count;
|
||||
}
|
||||
int operator()(value_type *code, value_type *erasures = 0, int erasures_count = 0)
|
||||
{
|
||||
return (*this)(reinterpret_cast<ValueType *>(code), reinterpret_cast<IndexType *>(erasures), erasures_count);
|
||||
}
|
||||
int compute_syndromes(value_type *code, value_type *syndromes)
|
||||
{
|
||||
return compute_syndromes(reinterpret_cast<ValueType *>(code), reinterpret_cast<ValueType *>(syndromes));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue