use of org.ddogleg.struct.GrowQueue_I8 in project BoofCV by lessthanoptimal.
the class ReidSolomonCodes method correctErrors.
/**
* Use Forney algorithm to compute correction values.
*
* @param message (Input/Output) The message which is to be corrected. Just the message. ECC not required.
* @param length_msg_ecc (Input) length of message and ecc code
* @param errorLocations (Input) locations of bytes in message with errors.
*/
void correctErrors(GrowQueue_I8 message, int length_msg_ecc, GrowQueue_I8 syndromes, GrowQueue_I8 errorLocator, GrowQueue_I32 errorLocations) {
// TODO avoid new
GrowQueue_I8 err_eval = new GrowQueue_I8();
findErrorEvaluator(syndromes, errorLocator, err_eval);
// Compute error positions
// TODO avoid new
GrowQueue_I8 X = GrowQueue_I8.zeros(errorLocations.size);
for (int i = 0; i < errorLocations.size; i++) {
int coef_pos = (length_msg_ecc - errorLocations.data[i] - 1);
X.data[i] = (byte) math.power(2, coef_pos);
// The commented out code below replicates exactly how the reference code works. This code above
// seems to work just as well and passes all the unit tests
// int coef_pos = math.max_value-(length_msg_ecc-errorLocations.data[i]-1);
// X.data[i] = (byte)math.power_n(2,-coef_pos);
}
GrowQueue_I8 err_loc_prime_tmp = new GrowQueue_I8(X.size);
// storage for error magnitude polynomial
for (int i = 0; i < X.size; i++) {
int Xi = X.data[i] & 0xFF;
int Xi_inv = math.inverse(Xi);
// Compute the polynomial derivative
err_loc_prime_tmp.size = 0;
for (int j = 0; j < X.size; j++) {
if (i == j)
continue;
err_loc_prime_tmp.data[err_loc_prime_tmp.size++] = (byte) GaliosFieldOps.subtract(1, math.multiply(Xi_inv, X.data[j] & 0xFF));
}
// compute the product, which is the denominator of Forney algorithm (errata locator derivative)
int err_loc_prime = 1;
for (int j = 0; j < err_loc_prime_tmp.size; j++) {
err_loc_prime = math.multiply(err_loc_prime, err_loc_prime_tmp.data[j] & 0xFF);
}
int y = math.polyEval_S(err_eval, Xi_inv);
y = math.multiply(math.power(Xi, 1), y);
// Compute the magnitude
int magnitude = math.divide(y, err_loc_prime);
// only apply a correction if it's part of the message and not the ECC
int loc = errorLocations.get(i);
if (loc < message.size)
message.data[loc] = (byte) ((message.data[loc] & 0xFF) ^ magnitude);
}
}
use of org.ddogleg.struct.GrowQueue_I8 in project BoofCV by lessthanoptimal.
the class ReidSolomonCodes method findErrorLocatorPolynomialBM.
/**
* Computes the error locator polynomial using Berlekamp-Massey algorithm [1]
*
* <p>[1] Massey, J. L. (1969), "Shift-register synthesis and BCH decoding" (PDF), IEEE Trans.
* Information Theory, IT-15 (1): 122–127</p>
*
* @param syndromes (Input) The syndromes
* @param errorLocator (Output) Error locator polynomial. Coefficients are large to small.
*/
void findErrorLocatorPolynomialBM(GrowQueue_I8 syndromes, GrowQueue_I8 errorLocator) {
// error polynomial
GrowQueue_I8 C = errorLocator;
// previous error polynomial
GrowQueue_I8 B = new GrowQueue_I8();
// TODO remove new from this function
initToOne(C, syndromes.size + 1);
initToOne(B, syndromes.size + 1);
GrowQueue_I8 tmp = new GrowQueue_I8(syndromes.size);
// int L = 0;
// int m = 1; // stores how much B is 'shifted' by
int b = 1;
for (int n = 0; n < syndromes.size; n++) {
// Compute discrepancy delta
int delta = syndromes.data[n] & 0xFF;
for (int j = 1; j < C.size; j++) {
delta ^= math.multiply(C.data[C.size - j - 1] & 0xFF, syndromes.data[n - j] & 0xFF);
}
// B = D^m * B
B.data[B.size++] = 0;
if (delta != 0) {
int scale = math.multiply(delta, math.inverse(b));
math.polyAddScaleB(C, B, scale, tmp);
if (B.size <= C.size) {
// if 2*L > N ---- Step 4
// m += 1;
} else {
// if 2*L <= N --- Step 5
B.setTo(C);
// L = n+1-L;
b = delta;
// m = 1;
}
C.setTo(tmp);
}
}
removeLeadingZeros(C);
}
use of org.ddogleg.struct.GrowQueue_I8 in project BoofCV by lessthanoptimal.
the class TestReidSolomonCodes method computeECC_python.
/**
* Compare against results from python tutorial
*/
@Test
public void computeECC_python() {
byte[] a = new byte[] { 0x40, (byte) 0xd2, 0x75, 0x47, 0x76, 0x17, 0x32, 0x06, 0x27, 0x26, (byte) 0x96, (byte) 0xc6, (byte) 0xc6, (byte) 0x96, 0x70, (byte) 0xec };
byte[] b = new byte[] { (byte) 0xbc, 0x2a, (byte) 0x90, 0x13, 0x6b, (byte) 0xaf, (byte) 0xef, (byte) 0xfd, 0x4b, (byte) 0xe0 };
GrowQueue_I8 message = new GrowQueue_I8();
GrowQueue_I8 ecc = new GrowQueue_I8();
message.data = a;
message.size = a.length;
ReidSolomonCodes alg = new ReidSolomonCodes(8, 0x11d);
alg.generator(10);
alg.computeECC(message, ecc);
assertEquals(10, ecc.size);
for (int i = 0; i < b.length; i++) {
assertEquals(b[i], ecc.data[i]);
}
}
use of org.ddogleg.struct.GrowQueue_I8 in project BoofCV by lessthanoptimal.
the class TestReidSolomonCodes method correct_random.
/**
* Randomly correct the message and ECC. See if the message is correctly reconstructed.
*/
@Test
public void correct_random() {
GrowQueue_I8 ecc = new GrowQueue_I8();
// should be able to recover from 4 errors
int nsyn = 10;
ReidSolomonCodes alg = new ReidSolomonCodes(8, primitive8);
alg.generator(nsyn);
for (int i = 0; i < 20000; i++) {
GrowQueue_I8 message = randomMessage(100);
GrowQueue_I8 corrupted = message.copy();
alg.computeECC(message, ecc);
// apply noise to the message
int numErrors = rand.nextInt(6);
for (int j = 0; j < numErrors; j++) {
int selected = rand.nextInt(message.size);
// make sure it changes even if the same number is selected twice
corrupted.data[selected] ^= (0x12 + j);
}
// corrupt the ecc code
if (numErrors < 5 && rand.nextInt(5) < 1) {
numErrors++;
ecc.data[rand.nextInt(ecc.size)] ^= 0x13;
}
alg.correct(corrupted, ecc);
assertEquals(corrupted.size, message.size);
for (int j = 0; j < corrupted.size; j++) {
assertEquals(corrupted.get(j), message.get(j));
}
}
}
use of org.ddogleg.struct.GrowQueue_I8 in project BoofCV by lessthanoptimal.
the class TestReidSolomonCodes method computeECC.
@Test
public void computeECC() {
GrowQueue_I8 message = randomMessage(50);
GrowQueue_I8 ecc = new GrowQueue_I8();
ReidSolomonCodes alg = new ReidSolomonCodes(8, primitive8);
alg.generator(6);
alg.computeECC(message, ecc);
assertEquals(6, ecc.size);
int numNotZero = 0;
for (int i = 0; i < ecc.size; i++) {
if (0 != ecc.data[i])
numNotZero++;
}
assertTrue(numNotZero >= 5);
// numerical properties are tested by computeSyndromes
}
Aggregations