gf2_poly(unsigned int num_symmetries) { gf2_poly g({1}); for (unsigned int i = 0; i < num_symmetries; i++) { g *= gf2_poly({GF2(0b1), GF2(2).pow(i)}); } data = g.data; }
vec_GF2 GF2MatrixUtils::solve(mat_GF2 A, vec_GF2 b) { uint32_t nextRow = 0; for (uint32_t j =0; j < A.NumCols(); j++) { uint32_t i; for (i=nextRow; i < A.NumRows(); i++) { if (A[i][j] == 1) { break; } } if (i==A.NumRows()) { continue; } if (A[i][j] == 1) { if (nextRow !=i) { swap(A[nextRow],A[i]); swap(b[nextRow],b[i]); } for (uint32_t k=nextRow+1; k < A.NumRows(); k++) { if (A[k][j] == 1) { A[k] = A[k] + A[nextRow]; b[k] = b[k] + b[nextRow]; } } nextRow++; } } vec_GF2 sol; sol.SetLength(A.NumCols(), GF2(0)); int32_t lastRow=A.NumRows()-1; while (A[lastRow][A.NumCols()-1]==0) { if ((A[lastRow]*sol) != b[lastRow]) { throw(system_error()); } lastRow--; if (lastRow == -1) { throw(system_error()); } } for (int32_t j=A.NumCols()-1; j >= 0; j--) { if (lastRow == -1) { throw(system_error()); } if (A[lastRow][j]==0) { continue; } if ((A[lastRow]*sol) != b[lastRow]) { sol[j]=1; } lastRow--; } return sol; }
friend std::pair<gf2_poly, gf2_poly> operator/(const gf2_poly& dividend, const gf2_poly& divisor) { auto output = dividend.data; auto normalizer = divisor[0]; for (size_t i = 0; i < dividend.size() - (divisor.size() - 1); i++) { auto coef = output[i]; if (coef != GF2(0)) { for (size_t j = 1; j < divisor.size(); j++) { output[i + j] += divisor[j] * coef; } } } auto separator = divisor.size() - 1; gf2_poly quotient; quotient.data.reserve(output.size() - separator); gf2_poly remainder; remainder.data.reserve(separator); std::move(output.begin(), output.end() - separator, std::back_inserter(quotient.data)); std::move(output.end() - separator, output.end(), std::back_inserter(remainder.data)); return {quotient, remainder}; }
/*! * This does not utilize any reproducible random number * generation nor can it's statistics be controlled. It is * intended entirely for debug and testing purposes. * * @return Randomly generated Galois Field (2) symbol. */ static GF2 random() { std::random_device generator; std::uniform_int_distribution<Symbol> distribution( 0, fieldSize-1); return GF2(distribution(generator)); }
gf2_poly& operator*=(const gf2_poly& rhs) { std::vector<GF2> result(size() + rhs.size() - 1, GF2(0)); for (size_t j = 0; j < rhs.size(); j++) { for (size_t i = 0; i < size(); i++) { result[i + j] += data[i] * rhs.data[j]; } } data = result; return *this; }
L::QRNSequence* L::Make::qrnSequence (int n, const Hypercube &h) { /* * 1agg Digital Sequences in Base 2 * | | * | \__ Generator Matrix 2 * | * \____ 1 - Normal * 2 - Gray-Code */ if (n >= 1000 && n < 2000) { int nn = n; int gen = nn % 100; nn /= 100; GM2* gm; try { gm = generatorMatrix2 (gen, h.getDimension()); } catch (GeneratorMatrixDoesNotExist &) { throw QRNSequenceDoesNotExist (n); } int type = nn % 10; nn /= 10; if (type >= 3) throw QRNSequenceDoesNotExist (n); typedef DigitalNet2Gray<u64> DN2G; QRNSequence* seq; switch (type) { case 1: seq = new QRNSequenceP<DN2G> (new DN2G (*gm, h)); break; case 2: seq = new QRNSequenceP<DN2G> (new DN2G (*gm, h, false)); break; default: throw InternalError (__FILE__, __LINE__); } delete gm; return seq; } /* * 2agg Digital Sequences in general base * | | * | \__ Generator Matrix Gen * | * \____ 0 - Naive * 1 - Normal * 2 - Gray-Code */ if (n >= 2000 && n < 3000) { int nn = n; int gen = nn % 100; nn /= 100; GMGen* gm; try { gm = generatorMatrixGen (gen, h.getDimension()); } catch (GeneratorMatrixDoesNotExist &) { throw QRNSequenceDoesNotExist (n); } int type = nn % 10; nn /= 10; if (type >= 3) throw QRNSequenceDoesNotExist (n); int base = gm->getBase(); bool prime = Prime::test (base); int vec = digitsRepresentable(static_cast<unsigned char>(base)); QRNSequence* seq; if (vec == 1) // if (1) { // Field types typedef LookupField <unsigned char> Fgen; typedef LookupFieldPow2 <unsigned char> Fpow2; typedef ModularArithmeticField<unsigned char> Fprime; // Field types used for Vector Space construction typedef LookupGaloisField <unsigned char> GFgen; typedef LookupGaloisFieldPow2<unsigned char> GFpow2; // Vector Space types typedef OneDimVectorSpace<Fgen> VSgen; typedef OneDimVectorSpace<Fpow2> VSpow2; typedef OneDimVectorSpace<Fprime> VSprime; typedef OneDimVectorSpace<GF2> VS2; // Digital Net types typedef DigitalNetGenNormal <VSgen, Index> NormalGen; typedef DigitalNetGenNaive <VSgen, Index> NaiveGen; typedef DigitalNetGenGray <VSgen, Index> GrayGen; typedef DigitalNetGenGray <VSpow2, Index> GrayPow2; typedef DigitalNetGenCyclicGray<VSprime, Index> CyclicPrime; typedef DigitalNetGenCyclicGray<VS2, Index> Cyclic2; switch (type) { case 0: seq = new QRNSequenceP<NaiveGen> (new NaiveGen ( VSgen(GFgen(base)), *gm, h)); break; case 1: seq = new QRNSequenceP<NormalGen> (new NormalGen ( VSgen(GFgen(base)), *gm, h)); break; case 2: { if (base == 2) seq = new QRNSequenceP<Cyclic2> (new Cyclic2 ( VS2(GF2()), *gm, h)); else if (prime) seq = new QRNSequenceP<CyclicPrime> (new CyclicPrime ( VSprime(Fprime(base)), *gm, h)); else if (base % 2 == 0) seq = new QRNSequenceP<GrayPow2> (new GrayPow2 ( VSpow2(GFpow2(base)), *gm, h)); else seq = new QRNSequenceP<GrayGen> (new GrayGen ( VSgen(GFgen(base)), *gm, h)); break; } default: throw InternalError (__FILE__, __LINE__); } } else // we can do vectorization { // Field types used for Vector Space construction typedef LookupGaloisField <unsigned char> GFgen; typedef LookupGaloisFieldPow2<unsigned char> GFpow2; // Vector Space types typedef LookupVectorSpace <unsigned char,unsigned char> VSgen; typedef LookupVectorSpacePow2<unsigned char,unsigned char> VSpow2; typedef VectorSpacePow2<u64> VSpow2full; // Digital Net types typedef DigitalNetGenNormal <VSgen, Index> NormalGen; typedef DigitalNetGenNaive <VSgen, Index> NaiveGen; typedef DigitalNetGenGray <VSgen, Index> GrayGen; typedef DigitalNetGenGray <VSpow2, Index> GrayPow2; typedef DigitalNetGenCyclicGray<VSgen, Index> CyclicGen; typedef DigitalNetGenCyclicGray<VSpow2, Index> CyclicPow2; VSgen x = VSgen(GFgen(base), vec); switch (type) { case 0: seq = new QRNSequenceP<NaiveGen> (new NaiveGen ( VSgen(GFgen(base), vec), *gm, h)); break; case 1: seq = new QRNSequenceP<NormalGen> (new NormalGen ( VSgen(GFgen(base), vec), *gm, h)); break; case 2: { if (base == 2) seq = new QRNSequenceP<CyclicPow2> (new CyclicPow2 ( VSpow2(GFpow2(base), vec), *gm, h)); else if (base % 2 == 0) { seq = new QRNSequenceP<GrayPow2> (new GrayPow2 ( VSpow2(GFpow2(base), vec), *gm, h)); } else if (prime) seq = new QRNSequenceP<CyclicGen> (new CyclicGen ( VSgen(GFgen(base), vec), *gm, h)); else seq = new QRNSequenceP<GrayGen> (new GrayGen ( VSgen(GFgen(base), vec), *gm, h)); break; } default: throw InternalError (__FILE__, __LINE__); } } delete gm; return seq; } /* * 9xxx Special Cases * | * \____ 0 - Halton */ switch (n) { case 9000: return new QRNSequenceT<Halton> (h); default: throw QRNSequenceDoesNotExist (n); } }
/*! * @param [in] x Right hand summand. * @return Galois Field (2) sum of *this and argument. */ GF2 operator+(const GF2 x) const { return GF2(x.m_data ^ m_data); }
/*! * @param [in] x Multiplier in multiplication operation. * @return Galois Field (2) product of *this and the argument */ GF2 operator*(const GF2 x) const { return GF2(x.m_data & m_data); }