![]() |
rssoft
0.0.0
Reed-Solomon codes library with soft decision decoding
|
Galois Field GF(q=2^m) class. Generates and holds lookup tables (LUT) for basic operations. Hosts basic operations and element representation conversions. More...
#include <GFq.h>
Public Member Functions | |
GFq (const int pwr, const GF2_Polynomial &primitive_poly) | |
GFq (const GFq &gf) | |
~GFq () | |
GFq & | operator= (const GFq &gf) |
bool | operator== (const GFq &gf) const |
bool | operator!= (const GFq &gf) const |
unsigned int | index (const GFq_Symbol value) const |
GFq_Symbol | alpha (const unsigned int power) const |
unsigned int | size () const |
unsigned int | pwr () const |
GFq_Symbol | add (const GFq_Symbol &a, const GFq_Symbol &b) const |
GFq_Symbol | sub (const GFq_Symbol &a, const GFq_Symbol &b) const |
GFq_Symbol | mul (const GFq_Symbol &a, const GFq_Symbol &b) const |
GFq_Symbol | div (const GFq_Symbol &a, const GFq_Symbol &b) const |
GFq_Symbol | exp (const GFq_Symbol &a, const int &n) const |
GFq_Symbol | inverse (const GFq_Symbol &val) const |
Private Member Functions | |
void | generate_field () |
GFq_Symbol | fast_modulus (GFq_Symbol x) const |
GFq_Symbol | gen_mul (const GFq_Symbol &a, const GFq_Symbol &b) const |
GFq_Symbol | gen_div (const GFq_Symbol &a, const GFq_Symbol &b) const |
GFq_Symbol | gen_exp (const GFq_Symbol &a, const unsigned int &n) const |
GFq_Symbol | gen_inverse (const GFq_Symbol &val) const |
Private Attributes | |
unsigned int | power |
m the power of 2 as in GF(2^m) | |
unsigned int | field_size |
Number of non null elements in the field. | |
const GF2_Polynomial & | primitive_poly |
Primitive polynomial. | |
unsigned int | prim_poly_hash |
Primitive polynomial hash coded. | |
GFq_Symbol * | alpha_to |
Exponential or anti-log unary operation LUT. | |
GFq_Symbol * | index_of |
Log unary operation LUT. | |
GFq_Symbol * | mul_inverse |
Multiplicative inverse unary operation LUT. | |
GFq_Symbol ** | mul_table |
Multiplication binary operation LUT. | |
GFq_Symbol ** | div_table |
Division binary operation LUT. | |
GFq_Symbol ** | exp_table |
Exponent binary operation LUT. | |
Friends | |
std::ostream & | operator<< (std::ostream &os, const GFq &gf) |
Galois Field GF(q=2^m) class. Generates and holds lookup tables (LUT) for basic operations. Hosts basic operations and element representation conversions.
rssoft::gf::GFq::GFq | ( | const int | pwr, |
const GF2_Polynomial & | primitive_poly | ||
) |
: power(pwr), field_size((1 << power) - 1), primitive_poly(_primitive_poly) { if (primitive(primitive_poly, pwr)) { alpha_to = new GFq_Symbol[field_size + 1]; index_of = new GFq_Symbol[field_size + 1]; #if !defined(NO_GFLUT) mul_table = new GFq_Symbol*[(field_size + 1)]; div_table = new GFq_Symbol*[(field_size + 1)]; exp_table = new GFq_Symbol*[(field_size + 1)]; mul_inverse = new GFq_Symbol[(field_size + 1) * 2]; for (unsigned int i = 0; i < (field_size + 1); i++) { mul_table[i] = new GFq_Symbol[(field_size + 1)]; div_table[i] = new GFq_Symbol[(field_size + 1)]; exp_table[i] = new GFq_Symbol[(field_size + 1)]; } #else mul_table = new GFq_Symbol *[1]; div_table = new GFq_Symbol *[1]; exp_table = new GFq_Symbol *[1]; mul_inverse = new GFq_Symbol [1]; #endif prim_poly_hash = 0xAAAAAAAA; unsigned int prim_poly_mono_power = 1; for (unsigned int i = 0; i <= power; i++) { if (i < power) { prim_poly_hash += ((i & 1) == 0) ? ( (prim_poly_hash << 7) ^ primitive_poly[i].uint_value() ^ (prim_poly_hash >> 3)) : (~((prim_poly_hash << 11) ^ primitive_poly[i].uint_value() ^ (prim_poly_hash >> 5))); } prim_poly_mono_power <<= 1; } generate_field(); } else { throw GF_Exception("Non primitive polynomial used to create GF(q) field"); } }
rssoft::gf::GFq::GFq | ( | const GFq & | gf | ) |
: primitive_poly(gf.primitive_poly) { power = gf.power; field_size = gf.field_size; prim_poly_hash = gf.prim_poly_hash; alpha_to = new GFq_Symbol[field_size + 1]; index_of = new GFq_Symbol[field_size + 1]; memcpy(alpha_to, gf.alpha_to, (field_size + 1) * sizeof(GFq_Symbol)); memcpy(index_of, gf.index_of, (field_size + 1) * sizeof(GFq_Symbol)); #if !defined(NO_GFLUT) mul_table = new GFq_Symbol*[(field_size + 1)]; div_table = new GFq_Symbol*[(field_size + 1)]; exp_table = new GFq_Symbol*[(field_size + 1)]; mul_inverse = new GFq_Symbol[(field_size + 1) * 2]; for (unsigned int i = 0; i < (field_size + 1); i++) { mul_table[i] = new GFq_Symbol[(field_size + 1)]; div_table[i] = new GFq_Symbol[(field_size + 1)]; exp_table[i] = new GFq_Symbol[(field_size + 1)]; } memcpy(mul_inverse, gf.mul_inverse, (field_size + 1) * sizeof(GFq_Symbol) * 2); memcpy(mul_table, gf.mul_table, (field_size + 1) * sizeof(GFq_Symbol*)); memcpy(div_table, gf.div_table, (field_size + 1) * sizeof(GFq_Symbol*)); memcpy(exp_table, gf.exp_table, (field_size + 1) * sizeof(GFq_Symbol*)); for (unsigned int i = 0; i < (field_size + 1); i++) { memcpy(mul_table[i], gf.mul_table[i], (field_size + 1) * sizeof(GFq_Symbol)); memcpy(div_table[i], gf.div_table[i], (field_size + 1) * sizeof(GFq_Symbol)); memcpy(exp_table[i], gf.exp_table[i], (field_size + 1) * sizeof(GFq_Symbol)); } #endif }
{ if (alpha_to != NULL) { delete[] alpha_to; } if (index_of != NULL) { delete[] index_of; } #if !defined(NO_GFLUT) for (unsigned int i = 0; i < (field_size + 1); i++) { if (mul_table[i] != NULL) { delete[] mul_table[i]; } if (div_table[i] != NULL) { delete[] div_table[i]; } if (exp_table[i] != NULL) { delete[] exp_table[i]; } } if (mul_table != NULL) { delete[] mul_table; } if (div_table != NULL) { delete[] div_table; } if (exp_table != NULL) { delete[] exp_table; } if (mul_inverse != NULL) { delete[] mul_inverse; } #endif }
GFq_Symbol rssoft::gf::GFq::add | ( | const GFq_Symbol & | a, |
const GFq_Symbol & | b | ||
) | const [inline] |
{
return (a ^ b);
}
GFq_Symbol rssoft::gf::GFq::alpha | ( | const unsigned int | power | ) | const [inline] |
GFq_Symbol rssoft::gf::GFq::div | ( | const GFq_Symbol & | a, |
const GFq_Symbol & | b | ||
) | const [inline] |
{ #if !defined(NO_GFLUT) return div_table[a][b]; #else if ((a == 0) || (b == 0)) { return 0; } else { return alpha_to[fast_modulus(index_of[a] - index_of[b] + field_size)]; } #endif }
GFq_Symbol rssoft::gf::GFq::exp | ( | const GFq_Symbol & | a, |
const int & | n | ||
) | const [inline] |
{ if (n == 0) { return 1; } else if (a == 0) { return 0; } else { unsigned int log_a = index_of[a]; unsigned int log_a_pwr_n = log_a * n; return alpha_to[log_a_pwr_n % field_size]; } }
GFq_Symbol rssoft::gf::GFq::fast_modulus | ( | GFq_Symbol | x | ) | const [private] |
{ while (x >= (int) field_size) { x -= (int) field_size; x = (x >> power) + (x & (int) field_size); } return x; }
GFq_Symbol rssoft::gf::GFq::gen_div | ( | const GFq_Symbol & | a, |
const GFq_Symbol & | b | ||
) | const [private] |
{ if ((a == 0) || (b == 0)) { return 0; } else { return alpha_to[fast_modulus(index_of[a] - index_of[b] + field_size)]; } }
GFq_Symbol rssoft::gf::GFq::gen_exp | ( | const GFq_Symbol & | a, |
const unsigned int & | n | ||
) | const [private] |
{ if (a != 0) { if (n == 0) { return 1; } else { return alpha_to[fast_modulus(index_of[a] * n)]; } } else { return 0; } }
GFq_Symbol rssoft::gf::GFq::gen_inverse | ( | const GFq_Symbol & | val | ) | const [private] |
{ return alpha_to[fast_modulus(field_size - index_of[val])]; }
GFq_Symbol rssoft::gf::GFq::gen_mul | ( | const GFq_Symbol & | a, |
const GFq_Symbol & | b | ||
) | const [private] |
{ if ((a == 0) || (b == 0)) { return 0; } else { return alpha_to[fast_modulus(index_of[a] + index_of[b])]; } }
void rssoft::gf::GFq::generate_field | ( | ) | [private] |
{ /* Note: It is assumed that the degree of the primitive polynomial will be equivelent to the m value as in GF(2^m) */ /* need to update using stanford method for prim-poly generation. */ int mask = 1; alpha_to[power] = 0; for (unsigned int i = 0; i < power; i++) { alpha_to[i] = mask; index_of[alpha_to[i]] = i; if (primitive_poly[i] != 0) { alpha_to[power] ^= mask; } mask <<= 1; } index_of[alpha_to[power]] = power; mask >>= 1; for (unsigned int i = power + 1; i < field_size; i++) { if (alpha_to[i - 1] >= mask) { alpha_to[i] = alpha_to[power] ^ ((alpha_to[i - 1] ^ mask) << 1); } else { alpha_to[i] = alpha_to[i - 1] << 1; } index_of[alpha_to[i]] = i; } index_of[0] = GFERROR; alpha_to[field_size] = 1; #if !defined(NO_GFLUT) for (unsigned int i = 0; i < field_size + 1; i++) { for (unsigned int j = 0; j < field_size + 1; j++) { mul_table[i][j] = gen_mul(i, j); div_table[i][j] = gen_div(i, j); exp_table[i][j] = gen_exp(i, j); } } for (unsigned int i = 0; i < (field_size + 1); i++) { mul_inverse[i] = gen_inverse(i); mul_inverse[i + (field_size + 1)] = mul_inverse[i]; } #endif }
unsigned int rssoft::gf::GFq::index | ( | const GFq_Symbol | value | ) | const [inline] |
Alpha based log
value | Symbol representation of the element |
{ return index_of[value]; }
GFq_Symbol rssoft::gf::GFq::inverse | ( | const GFq_Symbol & | val | ) | const [inline] |
{ #if !defined(NO_GFLUT) return mul_inverse[val]; #else return alpha_to[fast_modulus(field_size - index_of[val])]; #endif }
GFq_Symbol rssoft::gf::GFq::mul | ( | const GFq_Symbol & | a, |
const GFq_Symbol & | b | ||
) | const [inline] |
{ #if !defined(NO_GFLUT) return mul_table[a][b]; #else if ((a == 0) || (b == 0)) { return 0; } else { return alpha_to[fast_modulus(index_of[a] + index_of[b])]; } #endif }
bool rssoft::gf::GFq::operator!= | ( | const GFq & | gf | ) | const |
{ return ((this->power != gf.power) || (this->prim_poly_hash != gf.prim_poly_hash)); }
{ if (this == &gf) { return *this; } if (alpha_to != NULL) { delete[] alpha_to; } if (index_of != NULL) { delete[] index_of; } power = gf.power; field_size = gf.field_size; prim_poly_hash = gf.prim_poly_hash; memcpy(alpha_to, gf.alpha_to, (field_size + 1) * sizeof(GFq_Symbol)); memcpy(index_of, gf.index_of, (field_size + 1) * sizeof(GFq_Symbol)); #if !defined(NO_GFLUT) if (mul_table != NULL) { delete[] mul_table; } if (div_table != NULL) { delete[] div_table; } if (exp_table != NULL) { delete[] exp_table; } if (mul_inverse != NULL) { delete[] mul_inverse; } mul_table = new GFq_Symbol*[(field_size + 1)]; div_table = new GFq_Symbol*[(field_size + 1)]; exp_table = new GFq_Symbol*[(field_size + 1)]; mul_inverse = new GFq_Symbol[(field_size + 1) * 2]; for (unsigned int i = 0; i < (field_size + 1); i++) { mul_table[i] = new GFq_Symbol[(field_size + 1)]; div_table[i] = new GFq_Symbol[(field_size + 1)]; exp_table[i] = new GFq_Symbol[(field_size + 1)]; } memcpy(mul_inverse, gf.mul_inverse, (field_size + 1) * sizeof(GFq_Symbol) * 2); memcpy(mul_table, gf.mul_table, (field_size + 1) * sizeof(GFq_Symbol*)); memcpy(div_table, gf.div_table, (field_size + 1) * sizeof(GFq_Symbol*)); memcpy(exp_table, gf.exp_table, (field_size + 1) * sizeof(GFq_Symbol*)); for (unsigned int i = 0; i < (field_size + 1); i++) { memcpy(mul_table[i], gf.mul_table[i], (field_size + 1) * sizeof(GFq_Symbol)); memcpy(div_table[i], gf.div_table[i], (field_size + 1) * sizeof(GFq_Symbol)); memcpy(exp_table[i], gf.exp_table[i], (field_size + 1) * sizeof(GFq_Symbol)); } #endif return *this; }
bool rssoft::gf::GFq::operator== | ( | const GFq & | gf | ) | const |
{ return ((this->power == gf.power) && (this->prim_poly_hash == gf.prim_poly_hash)); }
unsigned int rssoft::gf::GFq::pwr | ( | ) | const [inline] |
unsigned int rssoft::gf::GFq::size | ( | ) | const [inline] |
Get the size of the field
{ return field_size; }
GFq_Symbol rssoft::gf::GFq::sub | ( | const GFq_Symbol & | a, |
const GFq_Symbol & | b | ||
) | const [inline] |
{
return (a ^ b);
}
std::ostream& operator<< | ( | std::ostream & | os, |
const GFq & | gf | ||
) | [friend] |
{ os << "GF(2^" << gf.pwr() << ")" << std::endl; os << "P = " << gf.primitive_poly << std::endl; os << "i\ta^i\tlog_a(i)" << std::endl; for(unsigned int i = 0; i < gf.field_size + 1; i++) { os << i << "\t" << gf.alpha_to[i] << "\t" << gf.index_of[i] << std::endl; } return os; }
GFq_Symbol* rssoft::gf::GFq::alpha_to [private] |
Exponential or anti-log unary operation LUT.
GFq_Symbol** rssoft::gf::GFq::div_table [private] |
Division binary operation LUT.
GFq_Symbol** rssoft::gf::GFq::exp_table [private] |
Exponent binary operation LUT.
unsigned int rssoft::gf::GFq::field_size [private] |
Number of non null elements in the field.
GFq_Symbol* rssoft::gf::GFq::index_of [private] |
Log unary operation LUT.
GFq_Symbol* rssoft::gf::GFq::mul_inverse [private] |
Multiplicative inverse unary operation LUT.
GFq_Symbol** rssoft::gf::GFq::mul_table [private] |
Multiplication binary operation LUT.
unsigned int rssoft::gf::GFq::power [private] |
m the power of 2 as in GF(2^m)
unsigned int rssoft::gf::GFq::prim_poly_hash [private] |
Primitive polynomial hash coded.
const GF2_Polynomial& rssoft::gf::GFq::primitive_poly [private] |
Primitive polynomial.