mirror of
https://github.com/aicodix/code.git
synced 2026-04-27 22:35:44 +00:00
used bitman to help clean up the mess
This commit is contained in:
parent
abe4edc419
commit
537aff62a2
4 changed files with 28 additions and 34 deletions
|
|
@ -8,6 +8,7 @@ Copyright 2018 Ahmet Inan <inan@aicodix.de>
|
||||||
#define BOSE_CHAUDHURI_HOCQUENGHEM_DECODER_HH
|
#define BOSE_CHAUDHURI_HOCQUENGHEM_DECODER_HH
|
||||||
|
|
||||||
#include "reed_solomon_error_correction.hh"
|
#include "reed_solomon_error_correction.hh"
|
||||||
|
#include "bitman.hh"
|
||||||
|
|
||||||
namespace CODE {
|
namespace CODE {
|
||||||
|
|
||||||
|
|
@ -24,11 +25,11 @@ public:
|
||||||
{
|
{
|
||||||
// $syndromes_i = code(pe^{FCR+i})$
|
// $syndromes_i = code(pe^{FCR+i})$
|
||||||
for (int i = 0; i < NR; ++i)
|
for (int i = 0; i < NR; ++i)
|
||||||
syndromes[i] = ValueType((code[0] >> 7) & 1);
|
syndromes[i] = ValueType(get_be_bit(code, 0));
|
||||||
for (int j = 1; j < N; ++j) {
|
for (int j = 1; j < N; ++j) {
|
||||||
IndexType root(FCR), pe(1);
|
IndexType root(FCR), pe(1);
|
||||||
for (int i = 0; i < NR; ++i) {
|
for (int i = 0; i < NR; ++i) {
|
||||||
syndromes[i] = fma(root, syndromes[i], ValueType((code[j / 8] >> (7 - j % 8)) & 1));
|
syndromes[i] = fma(root, syndromes[i], ValueType(get_be_bit(code, j)));
|
||||||
root *= pe;
|
root *= pe;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +47,7 @@ public:
|
||||||
assert(0 <= erasures_count && erasures_count <= NR);
|
assert(0 <= erasures_count && erasures_count <= NR);
|
||||||
if (0) {
|
if (0) {
|
||||||
for (int i = 0; i < erasures_count; ++i)
|
for (int i = 0; i < erasures_count; ++i)
|
||||||
code[erasures[i] / 8] &= ~(128 >> (erasures[i] % 8));
|
set_be_bit(code, erasures[i], 0);
|
||||||
}
|
}
|
||||||
ValueType syndromes[NR];
|
ValueType syndromes[NR];
|
||||||
if (!compute_syndromes(code, syndromes))
|
if (!compute_syndromes(code, syndromes))
|
||||||
|
|
@ -60,7 +61,7 @@ public:
|
||||||
if (1 < (int)magnitudes[i])
|
if (1 < (int)magnitudes[i])
|
||||||
return -1;
|
return -1;
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
code[(int)locations[i] / 8] ^= (int)magnitudes[i] << (7 - (int)locations[i] % 8);
|
xor_be_bit(code, (int)locations[i], (bool)magnitudes[i]);
|
||||||
int corrections_count = 0;
|
int corrections_count = 0;
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
corrections_count += !!magnitudes[i];
|
corrections_count += !!magnitudes[i];
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ Copyright 2018 Ahmet Inan <inan@aicodix.de>
|
||||||
#define BOSE_CHAUDHURI_HOCQUENGHEM_ENCODER_HH
|
#define BOSE_CHAUDHURI_HOCQUENGHEM_ENCODER_HH
|
||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
#include "bitman.hh"
|
||||||
|
|
||||||
namespace CODE {
|
namespace CODE {
|
||||||
|
|
||||||
|
|
@ -32,12 +33,11 @@ public:
|
||||||
--m_degree;
|
--m_degree;
|
||||||
assert(generator_degree + m_degree <= NP + 1);
|
assert(generator_degree + m_degree <= NP + 1);
|
||||||
for (int i = generator_degree; i >= 0; --i) {
|
for (int i = generator_degree; i >= 0; --i) {
|
||||||
if (!((generator[i/8]>>(i%8))&1))
|
if (!get_le_bit(generator, i))
|
||||||
continue;
|
continue;
|
||||||
generator[i/8] &= ~(1<<(i%8));
|
set_le_bit(generator, i, m&1);
|
||||||
generator[i/8] |= (m&1)<<(i%8);
|
|
||||||
for (int j = 1; j <= m_degree; ++j)
|
for (int j = 1; j <= m_degree; ++j)
|
||||||
generator[(i+j)/8] ^= ((m>>j)&1)<<((i+j)%8);
|
xor_le_bit(generator, i+j, (m>>j)&1);
|
||||||
}
|
}
|
||||||
generator_degree += m_degree;
|
generator_degree += m_degree;
|
||||||
}
|
}
|
||||||
|
|
@ -45,7 +45,7 @@ public:
|
||||||
if (0) {
|
if (0) {
|
||||||
std::cerr << "generator =";
|
std::cerr << "generator =";
|
||||||
for (int i = 0; i <= NP; ++i)
|
for (int i = 0; i <= NP; ++i)
|
||||||
std::cerr << " " << int((generator[i/8] >> (i%8))&1);
|
std::cerr << " " << get_le_bit(generator, i);
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -53,21 +53,16 @@ public:
|
||||||
{
|
{
|
||||||
// $code = data * x^{NP} + (data * x^{NP}) \mod{generator}$
|
// $code = data * x^{NP} + (data * x^{NP}) \mod{generator}$
|
||||||
for (int i = 0; i < NP; ++i)
|
for (int i = 0; i < NP; ++i)
|
||||||
code[(K+i)/8] &= ~(128>>((K+i)%8));
|
set_be_bit(code, K+i, 0);
|
||||||
for (int i = 0; i < K; ++i) {
|
for (int i = 0; i < K; ++i) {
|
||||||
if (((code[i/8]>>(7-i%8))&1) != ((code[K/8]>>(7-K%8))&1)) {
|
if (get_be_bit(code, i) != get_be_bit(code, K)) {
|
||||||
for (int j = 1; j < NP; ++j) {
|
for (int j = 1; j < NP; ++j)
|
||||||
code[(K+j-1)/8] &= ~(128>>((K+j-1)%8));
|
set_be_bit(code, K+j-1, get_le_bit(generator, NP-j) != get_be_bit(code, K+j));
|
||||||
code[(K+j-1)/8] |= (((generator[(NP-j)/8]>>((NP-j)%8))^(code[(K+j)/8]>>(7-(K+j)%8)))&1)<<(7-(K+j-1)%8);
|
set_be_bit(code, N-1, get_le_bit(generator, 0));
|
||||||
}
|
|
||||||
code[(N-1)/8] &= ~(128>>((N-1)%8));
|
|
||||||
code[(N-1)/8] |= (generator[0]&1)<<(7-(N-1)%8);
|
|
||||||
} else {
|
} else {
|
||||||
for (int j = 1; j < NP; ++j) {
|
for (int j = 1; j < NP; ++j)
|
||||||
code[(K+j-1)/8] &= ~(128>>((K+j-1)%8));
|
set_be_bit(code, K+j-1, get_be_bit(code, K+j));
|
||||||
code[(K+j-1)/8] |= ((code[(K+j)/8]>>(7-(K+j)%8))&1)<<(7-(K+j-1)%8);
|
set_be_bit(code, N-1, 0);
|
||||||
}
|
|
||||||
code[(N-1)/8] &= ~(128>>((N-1)%8));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ Copyright 2018 Ahmet Inan <inan@aicodix.de>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "bitman.hh"
|
||||||
#include "galois_field.hh"
|
#include "galois_field.hh"
|
||||||
#include "bose_chaudhuri_hocquenghem_decoder.hh"
|
#include "bose_chaudhuri_hocquenghem_decoder.hh"
|
||||||
|
|
||||||
|
|
@ -27,10 +28,8 @@ int main()
|
||||||
code[i] = target[i];
|
code[i] = target[i];
|
||||||
std::uniform_int_distribution<int> distribution(0, BCH::N-1);
|
std::uniform_int_distribution<int> distribution(0, BCH::N-1);
|
||||||
auto noise = std::bind(distribution, generator);
|
auto noise = std::bind(distribution, generator);
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i)
|
||||||
int n = noise();
|
CODE::xor_be_bit(code, noise(), 1);
|
||||||
code[n / 8] ^= 128 >> (n % 8);
|
|
||||||
}
|
|
||||||
decode(code);
|
decode(code);
|
||||||
for (int i = 0; i < L; ++i)
|
for (int i = 0; i < L; ++i)
|
||||||
assert(code[i] == target[i]);
|
assert(code[i] == target[i]);
|
||||||
|
|
@ -46,19 +45,17 @@ int main()
|
||||||
for (int i = 0; i < L; ++i)
|
for (int i = 0; i < L; ++i)
|
||||||
target[i] = 0;
|
target[i] = 0;
|
||||||
for (int i = 0, s = 0; i < BCH::K; ++i, s=(s*(s*s*51767+71287)+35149)&0xffffff)
|
for (int i = 0, s = 0; i < BCH::K; ++i, s=(s*(s*s*51767+71287)+35149)&0xffffff)
|
||||||
target[i/8] |= ((s^=s>>7)&1) << (7-i%8);
|
CODE::set_be_bit(target, i, (s^=s>>7)&1);
|
||||||
bool parity[BCH::NP] = { 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0 };
|
bool parity[BCH::NP] = { 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0 };
|
||||||
for (int i = 0; i < BCH::NP; ++i)
|
for (int i = 0; i < BCH::NP; ++i)
|
||||||
target[(BCH::K+i)/8] |= parity[i] << (7-(BCH::K+i)%8);
|
CODE::set_be_bit(target, BCH::K+i, parity[i]);
|
||||||
uint8_t *code = new uint8_t[L];
|
uint8_t *code = new uint8_t[L];
|
||||||
for (int i = 0; i < L; ++i)
|
for (int i = 0; i < L; ++i)
|
||||||
code[i] = target[i];
|
code[i] = target[i];
|
||||||
std::uniform_int_distribution<int> distribution(0, BCH::N-1);
|
std::uniform_int_distribution<int> distribution(0, BCH::N-1);
|
||||||
auto noise = std::bind(distribution, generator);
|
auto noise = std::bind(distribution, generator);
|
||||||
for (int i = 0; i < 12; ++i) {
|
for (int i = 0; i < 12; ++i)
|
||||||
int n = noise();
|
CODE::xor_be_bit(code, noise(), 1);
|
||||||
code[n / 8] ^= 128 >> (n % 8);
|
|
||||||
}
|
|
||||||
(*decode)(code);
|
(*decode)(code);
|
||||||
for (int i = 0; i < L; ++i)
|
for (int i = 0; i < L; ++i)
|
||||||
assert(code[i] == target[i]);
|
assert(code[i] == target[i]);
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ Copyright 2018 Ahmet Inan <inan@aicodix.de>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "bitman.hh"
|
||||||
#include "galois_field.hh"
|
#include "galois_field.hh"
|
||||||
#include "bose_chaudhuri_hocquenghem_encoder.hh"
|
#include "bose_chaudhuri_hocquenghem_encoder.hh"
|
||||||
|
|
||||||
|
|
@ -31,13 +32,13 @@ int main()
|
||||||
for (int i = 0; i < L; ++i)
|
for (int i = 0; i < L; ++i)
|
||||||
target[i] = 0;
|
target[i] = 0;
|
||||||
for (int i = 0, s = 0; i < BCH::K; ++i, s=(s*(s*s*51767+71287)+35149)&0xffffff)
|
for (int i = 0, s = 0; i < BCH::K; ++i, s=(s*(s*s*51767+71287)+35149)&0xffffff)
|
||||||
target[i/8] |= ((s^=s>>7)&1) << (7-i%8);
|
CODE::set_be_bit(target, i, (s^=s>>7)&1);
|
||||||
uint8_t *code = new uint8_t[L];
|
uint8_t *code = new uint8_t[L];
|
||||||
for (int i = 0; i < L; ++i)
|
for (int i = 0; i < L; ++i)
|
||||||
code[i] = target[i];
|
code[i] = target[i];
|
||||||
bool parity[BCH::NP] = { 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0 };
|
bool parity[BCH::NP] = { 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0 };
|
||||||
for (int i = 0; i < BCH::NP; ++i)
|
for (int i = 0; i < BCH::NP; ++i)
|
||||||
target[(BCH::K+i)/8] |= parity[i] << (7-(BCH::K+i)%8);
|
CODE::set_be_bit(target, BCH::K+i, parity[i]);
|
||||||
(*encode)(code);
|
(*encode)(code);
|
||||||
for (int i = 0; i < L; ++i)
|
for (int i = 0; i < L; ++i)
|
||||||
assert(code[i] == target[i]);
|
assert(code[i] == target[i]);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue