![]() |
rssoft
0.0.0
Reed-Solomon codes library with soft decision decoding
|
Univariate polynomials with coefficients in GF(2^m) More...
#include <GFq_Polynomial.h>
Public Member Functions | |
GFq_Polynomial (const GFq &_gf) | |
GFq_Polynomial (const GFq &_gf, const unsigned int size, GFq_Element *gfe=NULL) | |
GFq_Polynomial (const GFq &_gf, const std::vector< GFq_Element > &gfe) | |
GFq_Polynomial (const GFq_Polynomial &polynomial) | |
GFq_Polynomial (const GFq_Element &gfe) | |
~GFq_Polynomial () | |
void | init (const std::vector< GFq_Element > &_poly) |
bool | is_valid () const |
bool | is_zero () const |
bool | is_one () const |
unsigned int | deg () const |
const GFq & | field () const |
const std::vector< GFq_Element > & | get_poly () const |
std::vector< GFq_Element > & | get_poly_for_update () |
void | get_poly_symbols (std::vector< GFq_Symbol > &symbols, unsigned int size=0) const |
void | set_degree (const unsigned int &x) |
GFq_Polynomial & | operator= (const GFq_Polynomial &polynomial) |
GFq_Polynomial & | operator= (const GFq_Element &gfe) |
GFq_Polynomial & | operator+= (const GFq_Polynomial &polynomial) |
GFq_Polynomial & | operator+= (const GFq_Element &gfe) |
GFq_Polynomial & | operator-= (const GFq_Polynomial &polynomial) |
GFq_Polynomial & | operator-= (const GFq_Element &gfe) |
GFq_Polynomial & | operator*= (const GFq_Polynomial &polynomial) |
GFq_Polynomial & | operator*= (const GFq_Element &gfe) |
GFq_Polynomial & | operator/= (const GFq_Polynomial &divisor) |
GFq_Polynomial & | operator/= (const GFq_Element &gfe) |
GFq_Polynomial & | operator%= (const GFq_Polynomial &divisor) |
GFq_Polynomial & | operator%= (const unsigned int &power) |
GFq_Polynomial & | operator^= (const int &n) |
GFq_Polynomial & | operator<<= (const unsigned int &n) |
GFq_Polynomial & | operator>>= (const unsigned int &n) |
GFq_Element & | operator[] (const unsigned int &term) |
GFq_Element | operator() (const GFq_Element &value) |
GFq_Element | operator() (GFq_Symbol value) |
const GFq_Element & | operator[] (const unsigned int &term) const |
const GFq_Element | operator() (const GFq_Element &value) const |
const GFq_Element | operator() (GFq_Symbol value) const |
bool | operator== (const GFq_Polynomial &polynomial) const |
bool | operator!= (const GFq_Polynomial &polynomial) const |
GFq_Polynomial | derivative () |
GFq_Element | make_monic () |
void | rootChien (std::vector< GFq_Element > &roots) |
void | set_alpha_format (bool _alpha_format) |
Protected Attributes | |
const GFq & | gf |
Reference to the Galois Field of the coefficients. | |
std::vector< GFq_Element > | poly |
Coefficients vector. | |
bool | alpha_format |
Friends | |
std::ostream & | operator<< (std::ostream &os, const GFq_Polynomial &polynomial) |
Univariate polynomials with coefficients in GF(2^m)
rssoft::gf::GFq_Polynomial::GFq_Polynomial | ( | const GFq & | _gf | ) |
Constructs a new polynomial with coefficients in the specified GF(2^m)
_gf | The coefficients GF(2^m) |
: gf(_gf), alpha_format(false) { poly.clear(); }
rssoft::gf::GFq_Polynomial::GFq_Polynomial | ( | const GFq & | _gf, |
const unsigned int | size, | ||
GFq_Element * | gfe = NULL |
||
) |
Constructs a new polynomial with coefficients in the specified GF(2^m) with the specified coefficients
_gf | The coefficients GF(2^m) |
size | The number of coefficients |
gfe | Coefficients array in increasing powers of variable |
: gf(_gf), alpha_format(false) { if (gfe != NULL) { poly.assign(gfe, gfe + size); } else { poly.assign(size, GFq_Element(gf, 0)); } }
rssoft::gf::GFq_Polynomial::GFq_Polynomial | ( | const GFq & | _gf, |
const std::vector< GFq_Element > & | gfe | ||
) |
Constructs a new polynomial with coefficients in the specified GF(2^m) with the specified coefficients
_gf | The coefficients GF(2^m) |
gfe | Coefficients vector in increasing powers of variable |
: gf(_gf), alpha_format(false), poly(gfe.begin(), gfe.end()) { }
rssoft::gf::GFq_Polynomial::GFq_Polynomial | ( | const GFq_Polynomial & | polynomial | ) |
Copy constructor
polynomial | Reference of the polynomial to copy |
: gf(polynomial.gf) { poly = polynomial.poly; alpha_format = polynomial.alpha_format; }
rssoft::gf::GFq_Polynomial::GFq_Polynomial | ( | const GFq_Element & | gfe | ) |
Constructs a zero degree polynomial with the given element as coefficient. The reference Galois Field is taken from the element
: gf(gfe.field()), alpha_format(false) { poly.clear(); poly.push_back(gfe); }
rssoft::gf::GFq_Polynomial::~GFq_Polynomial | ( | ) | [inline] |
Destructor
{ }
unsigned int rssoft::gf::GFq_Polynomial::deg | ( | ) | const |
Degree of the polynomial
{ return static_cast<unsigned int>(poly.size() - 1); }
Calculates the derivative of a polynomial
{ if ((*this).poly.size() > 1) { GFq_Polynomial deriv(gf, deg()); for (unsigned int i = 0; i < poly.size() - 1; i++) { if (((i + 1) & 1) == 1) // odd power => (bX^n)' = nbX^(n-1) = bX^(n-1) { deriv.poly[i] = poly[i + 1]; } else { deriv.poly[i] = 0; // even power => (bX^n)' = nbX^(n-1) = 0X^(n-1) = 0 (eliminated) } } simplify(deriv); return deriv; } else { return GFq_Polynomial(gf, 0); } }
const GFq & rssoft::gf::GFq_Polynomial::field | ( | ) | const |
Reference to the Galois Field of the coefficients of the polynomial
{ return gf; }
const std::vector< GFq_Element > & rssoft::gf::GFq_Polynomial::get_poly | ( | ) | const |
Gets a constant reference to the coefficients vector
{ return poly; }
std::vector< GFq_Element > & rssoft::gf::GFq_Polynomial::get_poly_for_update | ( | ) |
Gets a modifiable reference to the coefficients vector
{ return poly; }
void rssoft::gf::GFq_Polynomial::get_poly_symbols | ( | std::vector< GFq_Symbol > & | symbols, |
unsigned int | size = 0 |
||
) | const [inline] |
Gets the coefficients vector as symbols
{ symbols.resize((size == 0 ? poly.size() : size)); std::transform(poly.begin(), poly.end(), symbols.begin(), gfq_element_to_symbol); }
void rssoft::gf::GFq_Polynomial::init | ( | const std::vector< GFq_Element > & | _poly | ) |
Initializes polynomial with a vector of coefficients in increasing power of variable
{ poly = _poly; }
bool rssoft::gf::GFq_Polynomial::is_one | ( | ) | const |
bool rssoft::gf::GFq_Polynomial::is_valid | ( | ) | const |
Tells if the polynomial has coefficients
{ return (poly.size() > 0); }
bool rssoft::gf::GFq_Polynomial::is_zero | ( | ) | const |
bool rssoft::gf::GFq_Polynomial::operator!= | ( | const GFq_Polynomial & | polynomial | ) | const |
{ return !(*this == polynomial); }
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator%= | ( | const GFq_Polynomial & | divisor | ) |
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator%= | ( | const unsigned int & | power | ) |
GFq_Element rssoft::gf::GFq_Polynomial::operator() | ( | const GFq_Element & | value | ) |
GFq_Element rssoft::gf::GFq_Polynomial::operator() | ( | GFq_Symbol | value | ) |
{ return (*this)(GFq_Element(gf, value)); }
const GFq_Element rssoft::gf::GFq_Polynomial::operator() | ( | const GFq_Element & | value | ) | const |
const GFq_Element rssoft::gf::GFq_Polynomial::operator() | ( | GFq_Symbol | value | ) | const |
{ return (*this)(GFq_Element(gf, value)); }
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator*= | ( | const GFq_Polynomial & | polynomial | ) |
{ if (gf == polynomial.gf) { GFq_Polynomial product(gf, deg() + polynomial.deg() + 1); for (unsigned int i = 0; i < poly.size(); i++) { for (unsigned int j = 0; j < polynomial.poly.size(); j++) { product.poly[i + j] += poly[i] * polynomial.poly[j]; } } simplify(product); poly = product.poly; } return *this; }
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator*= | ( | const GFq_Element & | gfe | ) |
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator+= | ( | const GFq_Polynomial & | polynomial | ) |
{ if (gf == polynomial.gf) { if (poly.size() < polynomial.poly.size()) { unsigned int j = 0; for (unsigned int i = 0; i < poly.size(); i++) { poly[i] += polynomial.poly[j++]; } for (; j < polynomial.poly.size(); j++) { poly.push_back(polynomial.poly[j]); } } else { unsigned int i = 0; for (unsigned int j = 0; j < polynomial.poly.size(); j++) { poly[i++] += polynomial.poly[j]; } } simplify(*this); } return *this; }
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator+= | ( | const GFq_Element & | gfe | ) |
{ poly[0] += gfe; return *this; }
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator-= | ( | const GFq_Polynomial & | polynomial | ) |
{ return (*this += gfe); }
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator-= | ( | const GFq_Element & | gfe | ) |
{ poly[0] -= gfe; return *this; }
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator/= | ( | const GFq_Polynomial & | divisor | ) |
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator/= | ( | const GFq_Element & | gfe | ) |
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator<<= | ( | const unsigned int & | n | ) |
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator= | ( | const GFq_Polynomial & | polynomial | ) |
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator= | ( | const GFq_Element & | gfe | ) |
bool rssoft::gf::GFq_Polynomial::operator== | ( | const GFq_Polynomial & | polynomial | ) | const |
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator>>= | ( | const unsigned int & | n | ) |
GFq_Element & rssoft::gf::GFq_Polynomial::operator[] | ( | const unsigned int & | term | ) |
const GFq_Element & rssoft::gf::GFq_Polynomial::operator[] | ( | const unsigned int & | term | ) | const |
GFq_Polynomial & rssoft::gf::GFq_Polynomial::operator^= | ( | const int & | n | ) |
{ if (n == 0) // P^0 = 1 { poly.clear(); poly.push_back(GFq_Element(gf, 1)); } else if (n > 1) { GFq_Polynomial result = *this; for (unsigned int i=0; i<n-1; i++) { result *= *this; } *this = result; } return *this; }
void rssoft::gf::GFq_Polynomial::rootChien | ( | std::vector< GFq_Element > & | roots | ) |
Find non null roots of polynomial by Chien search. Basically this is an exhaustive search optimized for hardware implementation but is also interesting in software. Includes null root afterwards if constant coefficient is zero. see: http://www.stanford.edu/class/ee387/handouts/notes7.pdf
roots | Vector of root field elements filled by the method |
{ std::vector<GFq_Element> wpoly(poly); const GFq_Element zero(gf,0); if (poly[0].is_zero()) { roots.push_back(zero); } for (unsigned int i=0; i < gf.size(); i++) { GFq_Element sum = std::accumulate(wpoly.begin(), wpoly.end(), zero); if (sum.is_zero()) { roots.push_back(GFq_Element(gf,gf.alpha(i))); } for (unsigned int j=0; j<wpoly.size(); j++) { wpoly[j] *= gf.alpha(j); } } }
void rssoft::gf::GFq_Polynomial::set_alpha_format | ( | bool | _alpha_format | ) | [inline] |
Sets the output of coefficients in a power of alpha (printed a^i) ot binary representation
_alpha_format | true: power of alpha representation. false: binary representation |
{ alpha_format = _alpha_format; }
void rssoft::gf::GFq_Polynomial::set_degree | ( | const unsigned int & | x | ) |
std::ostream& operator<< | ( | std::ostream & | os, |
const GFq_Polynomial & | polynomial | ||
) | [friend] |
Prints a polynomial to an output stream
{ if (polynomial.deg() >= 0) { bool is_null = true; bool first_coeff = true; for (unsigned int i = 0; i < polynomial.poly.size(); i++) { GFq_Symbol coeff = polynomial.poly[i].poly(); if (coeff != 0) { is_null = false; os << ((!first_coeff) ? "+ " : ""); if (polynomial.alpha_format) { GFq_Symbol log_alpha = polynomial.poly[i].index(); if (log_alpha == 0) { if (i == 0) { os << "1 "; } else { os << ""; } } else if (log_alpha == 1) { os << "a" << ((!first_coeff) ? "*" : " "); } else { os << "a^" << log_alpha << ((!first_coeff) ? "*" : " "); } } else { if (coeff == 1) { if (i != 0) { os << ""; } else { os << coeff << " "; } } else { os << coeff << ((!first_coeff) ? "*" : " "); } } if (i != 0) { if (i == 1) { os << "X "; } else { os << "X^" << i << " "; } } first_coeff = false; } } if (is_null) { os << "0"; } } return os; }
bool rssoft::gf::GFq_Polynomial::alpha_format [protected] |
const GFq& rssoft::gf::GFq_Polynomial::gf [protected] |
Reference to the Galois Field of the coefficients.
std::vector<GFq_Element> rssoft::gf::GFq_Polynomial::poly [protected] |
Coefficients vector.