[mathicgb] 38/393: Migrated QuadMatrixBuilder to use a hash table and made F4Matrix not defer to a fallback on clasically reducing an S-pair. Fixed some bugs that was corrupting hash values.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:29 UTC 2015
This is an automated email from the git hooks/post-receive script.
dtorrance-guest pushed a commit to branch upstream
in repository mathicgb.
commit 5edd09598ce1864169f65ee1a9cce5751e65d6fd
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Fri Sep 28 18:06:55 2012 +0200
Migrated QuadMatrixBuilder to use a hash table and made F4Matrix not defer to a fallback on clasically reducing an S-pair. Fixed some bugs that was corrupting hash values.
---
src/mathicgb/F4MatrixBuilder.cpp | 4 ++++
src/mathicgb/F4Reducer.cpp | 19 +++++------------
src/mathicgb/Poly.cpp | 10 ++++++---
src/mathicgb/PolyRing.cpp | 9 ++++++--
src/mathicgb/PolyRing.hpp | 22 ++++++++++++++-----
src/mathicgb/QuadMatrixBuilder.hpp | 43 ++++++++++++++++++++++++++++++++++++++
src/test/F4MatrixReducer.cpp | 1 +
7 files changed, 84 insertions(+), 24 deletions(-)
diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
index 23bc588..ad33cf8 100755
--- a/src/mathicgb/F4MatrixBuilder.cpp
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -32,6 +32,7 @@ void F4MatrixBuilder::addRowToMatrix
task.multiple = ring().allocMonomial();
ring().monomialCopy(multiple, task.multiple);
+ MATHICGB_ASSERT(ring().hashValid(task.multiple));
mTodo.push_back(task);
}
@@ -46,6 +47,7 @@ void F4MatrixBuilder::buildMatrixAndClear(QuadMatrix& matrix) {
typedef std::vector<RowTask>::iterator TaskIter;
TaskIter end = mTodo.end();
for (TaskIter it = mTodo.begin(); it != end; ++it) {
+ MATHICGB_ASSERT(ring().hashValid(it->multiple));
ring().monomialMult(it->multiple, it->poly->getLeadMonomial(), mono);
LeftRightColIndex leadCol = mBuilder.findColumn(mono);
it->useAsReducer = !leadCol.valid();
@@ -60,6 +62,7 @@ void F4MatrixBuilder::buildMatrixAndClear(QuadMatrix& matrix) {
// we are calling here can add more items to mTodo.
while (!mTodo.empty()) {
RowTask task = mTodo.back();
+ MATHICGB_ASSERT(ring().hashValid(task.multiple));
mTodo.pop_back();
if (task.useAsReducer)
appendRowTop(task.multiple, *task.poly);
@@ -90,6 +93,7 @@ F4MatrixBuilder::createOrFindColumnOf(const_monomial mono) {
task.multiple = ring().allocMonomial();
ring().monomialDivideToNegative
(mono, task.poly->getLeadMonomial(), task.multiple);
+ MATHICGB_ASSERT(ring().hashValid(task.multiple));
mTodo.push_back(task);
return LeftRightColIndex(mBuilder.createColumnLeft(mono), true);
diff --git a/src/mathicgb/F4Reducer.cpp b/src/mathicgb/F4Reducer.cpp
index 3d79ff0..5e865db 100755
--- a/src/mathicgb/F4Reducer.cpp
+++ b/src/mathicgb/F4Reducer.cpp
@@ -28,13 +28,6 @@ std::unique_ptr<Poly> F4Reducer::classicTailReduce
std::unique_ptr<Poly> F4Reducer::classicReduceSPoly
(const Poly& a, const Poly& b, const PolyBasis& basis) {
- std::unique_ptr<Poly> p;
- {
- p = mFallback->classicReduceSPoly(a, b, basis);
- mSigStats = mFallback->sigStats();
- mClassicStats = mFallback->classicStats();
- }
-
QuadMatrix qm;
{
F4MatrixBuilder builder(basis);
@@ -49,15 +42,13 @@ std::unique_ptr<Poly> F4Reducer::classicReduceSPoly
{
F4MatrixReducer red;
red.reduce(basis.ring(), qm, reduced);
- if (reduced.rowCount() > 0) {
- MATHICGB_ASSERT(reduced.rowCount() == 1);
- Poly q(&basis.ring());
- reduced.rowToPolynomial(0, qm.rightColumnMonomials, q);
- MATHICGB_ASSERT(q == *p);
- } else
- MATHICGB_ASSERT(p->isZero());
}
+ auto p = make_unique<Poly>(&basis.ring());
+ if (reduced.rowCount() > 0) {
+ MATHICGB_ASSERT(reduced.rowCount() == 1);
+ reduced.rowToPolynomial(0, qm.rightColumnMonomials, *p);
+ }
return p;
}
diff --git a/src/mathicgb/Poly.cpp b/src/mathicgb/Poly.cpp
index 79e0a8f..18243e1 100755
--- a/src/mathicgb/Poly.cpp
+++ b/src/mathicgb/Poly.cpp
@@ -22,6 +22,7 @@ void Poly::copy(Poly &result) const
std::copy(coeffs.begin(), coeffs.end(), result.coeffs.begin());
std::copy(monoms.begin(), monoms.end(), result.monoms.begin());
}
+
void Poly::appendTerm(coefficient a, const_monomial m)
{
// the monomial will be copied on.
@@ -30,11 +31,13 @@ void Poly::appendTerm(coefficient a, const_monomial m)
exponent const * e = m.unsafeGetRepresentation();
monoms.insert(monoms.end(), e, e + len);
}
+
void Poly::append(iterator &first, iterator &last)
{
for ( ; first != last; ++first)
appendTerm(first.getCoefficient(), first.getMonomial());
}
+
Poly *Poly::copy() const
{
Poly *const_this = const_cast<Poly *>(this);
@@ -228,9 +231,10 @@ void Poly::parse(std::istream &i)
R->coefficientFromInt(b,a);
coeffs.push_back(b);
if (isalpha(next) || next == '<')
- {
- R->monomialParse(i, m);
- }
+ R->monomialParse(i, m);
+ else
+ R->monomialSetIdentity(m); // have to do this to set hash value
+ MATHICGB_ASSERT(ring().hashValid(m));
next = i.peek();
if (next == '>') i.get();
}
diff --git a/src/mathicgb/PolyRing.cpp b/src/mathicgb/PolyRing.cpp
index c6a5db2..0f29bbd 100755
--- a/src/mathicgb/PolyRing.cpp
+++ b/src/mathicgb/PolyRing.cpp
@@ -11,6 +11,10 @@
#include <cstdlib>
#include <limits>
+bool PolyRing::hashValid(const_monomial m) const {
+ return monomialHashValue(m) == computeHashValue(m);
+}
+
PolyRing::PolyRing(long p0,
int nvars,
int nweights)
@@ -144,7 +148,7 @@ void PolyRing::monomialFindSignature(ConstMonomial v1,
else
weight -= t1[i] = u1[i];
}
-#ifdef DEBUG
+#ifdef MATHICGB_DEBUG
setWeightsOnly(t1);
ASSERT(t1[mNumVars + 1] == weight);
#endif
@@ -408,6 +412,7 @@ void PolyRing::monomialCopy(const_monomial a, monomial &result) const
for (size_t i = mHashIndex; i != static_cast<size_t>(-1); --i)
result[i] = a[i];
}
+
void PolyRing::monomialQuotientAndMult(const_monomial a,
const_monomial b,
const_monomial c,
@@ -430,7 +435,7 @@ void PolyRing::setWeightsAndHash(monomial a) const
a++;
for (size_t i = 0; i < mNumVars; ++i)
hash += a[i] * mHashVals[i];
- a[mHashIndex - 1] = hash;
+ a[mHashIndex - 1] = hash; // index-1 as we did ++a above
}
void PolyRing::monomialFindSignatures(const_monomial v1,
diff --git a/src/mathicgb/PolyRing.hpp b/src/mathicgb/PolyRing.hpp
index 803dbd2..c69d6e1 100755
--- a/src/mathicgb/PolyRing.hpp
+++ b/src/mathicgb/PolyRing.hpp
@@ -325,6 +325,8 @@ public:
inline void setHashOnly(Monomial& a) const;
+ bool hashValid(const_monomial m) const;
+
bool weightsCorrect(ConstMonomial a) const;
int monomialCompare(ConstMonomial a,
@@ -529,6 +531,8 @@ public:
void resetCoefficientStats() const;
private:
+ inline size_t computeHashValue(const_monomial a1) const;
+
long mCharac; // p=mCharac: ring is ZZ/p
size_t mNumVars;
int mNumWeights; // stored as negative of weight vectors
@@ -593,14 +597,19 @@ inline void PolyRing::setWeightsOnly(Monomial& a1) const
}
}
-inline void PolyRing::setHashOnly(Monomial& a1) const
-{
- exponent *a = a1.unsafeGetRepresentation();
+inline size_t PolyRing::computeHashValue(const_monomial a1) const {
+ const exponent* a = a1.unsafeGetRepresentation();
int hash = *a;
a++;
for (size_t i = 0; i < mNumVars; ++i)
hash += a[i] * mHashVals[i];
- a[mHashIndex - 1] = hash;
+ return hash;
+}
+
+inline void PolyRing::setHashOnly(Monomial& a1) const
+{
+ exponent* a = a1.unsafeGetRepresentation();
+ a[mHashIndex] = computeHashValue(a1);
}
inline int PolyRing::monomialCompare(ConstMonomial a, ConstMonomial b) const
@@ -656,8 +665,11 @@ inline void PolyRing::monomialDivideToNegative(ConstMonomial a,
ConstMonomial b,
Monomial& result) const
{
- for (size_t i = 0; i <= this->mTopIndex; ++i)
+ for (size_t i = 0; i <= mHashIndex; ++i)
result[i] = a[i] - b[i];
+ MATHICGB_ASSERT(result[mHashIndex] == a[mHashIndex] - b[mHashIndex]);
+ MATHICGB_ASSERT(!hashValid(a) || !hashValid(b) || hashValid(result));
+ MATHICGB_ASSERT(computeHashValue(result) == computeHashValue(a) - computeHashValue(b));
}
inline bool PolyRing::monomialRelativelyPrime(ConstMonomial a,
diff --git a/src/mathicgb/QuadMatrixBuilder.hpp b/src/mathicgb/QuadMatrixBuilder.hpp
index 4255b7d..48c8c69 100755
--- a/src/mathicgb/QuadMatrixBuilder.hpp
+++ b/src/mathicgb/QuadMatrixBuilder.hpp
@@ -1,12 +1,17 @@
#ifndef MATHICGB_QUAD_MATRIX_BUILDER_GUARD
#define MATHICGB_QUAD_MATRIX_BUILDER_GUARD
+#define MATHICGB_USE_QUADMATRIX_STD_HASH
+
#include "SparseMatrix.hpp"
#include "PolyRing.hpp"
#include <vector>
#include <map>
#include <string>
#include <ostream>
+#ifdef MATHICGB_USE_QUADMATRIX_STD_HASH
+#include <unordered_map>
+#endif
class FreeModuleOrder;
class QuadMatrix;
@@ -21,7 +26,11 @@ class QuadMatrixBuilder {
typedef SparseMatrix::Scalar Scalar;
QuadMatrixBuilder(const PolyRing& ring):
+#ifndef MATHICGB_USE_QUADMATRIX_STD_HASH
mMonomialToCol(ArbitraryOrdering(ring)) {}
+#else
+ mMonomialToCol(100, Hash(ring), Equal(ring)) {}
+#endif
/// The index of a column that can be either on the left or the
/// right side. The largest representable ColIndex is an invalid
@@ -198,7 +207,11 @@ class QuadMatrixBuilder {
// The key comparer object already has a ring reference - we might
// as well use that one instead of adding another reference to
// this object.
+#ifndef MATHICGB_USE_QUADMATRIX_STD_HASH
return mMonomialToCol.key_comp().ring();
+#else
+ return mMonomialToCol.key_eq().ring();
+#endif
}
ColIndex leftColCount() const {
@@ -221,6 +234,7 @@ private:
MonomialsType mMonomialsLeft;
MonomialsType mMonomialsRight;
+#ifndef MATHICGB_USE_QUADMATRIX_STD_HASH
/// We need SOME ordering to make std::map work.
class ArbitraryOrdering {
public:
@@ -237,6 +251,35 @@ private:
typedef std::map<const_monomial, LeftRightColIndex, ArbitraryOrdering>
MonomialToColType;
MonomialToColType mMonomialToCol;
+#else
+ struct Hash {
+ public:
+ Hash(const PolyRing& ring): mRing(ring) {}
+ size_t operator()(const_monomial m) const {
+ MATHICGB_ASSERT(mRing.hashValid(m));
+ return mRing.monomialHashValue(m);
+ }
+ const PolyRing& ring() const {return mRing;}
+
+ private:
+ const PolyRing& mRing;
+ };
+ struct Equal {
+ public:
+ Equal(const PolyRing& ring): mRing(ring) {}
+ size_t operator()(const_monomial a, const_monomial b) const {
+ return mRing.monomialEQ(a, b);
+ }
+ const PolyRing& ring() const {return mRing;}
+
+ private:
+ const PolyRing& mRing;
+ };
+
+ typedef std::unordered_map<const_monomial, LeftRightColIndex, Hash, Equal>
+ MonomialToColType;
+ MonomialToColType mMonomialToCol;
+#endif
SparseMatrix mTopLeft;
SparseMatrix mTopRight;
diff --git a/src/test/F4MatrixReducer.cpp b/src/test/F4MatrixReducer.cpp
index 5fbf6c5..781df0a 100755
--- a/src/test/F4MatrixReducer.cpp
+++ b/src/test/F4MatrixReducer.cpp
@@ -20,6 +20,7 @@ TEST(F4MatrixReducer, Reduce) {
size_t count = 0;
for (Poly::iterator it = p.begin(); it != p.end(); ++it) {
monomial mono = it.getMonomial();
+ MATHICGB_ASSERT(ring->hashValid(mono));
if (count < 4)
m.leftColumnMonomials.push_back(mono);
else
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/mathicgb.git
More information about the debian-science-commits
mailing list