[mathicgb] 356/393: Replaced the interface and implementation of PolyHashTable with the better hash table from BjarkeGeobucket2. That made BjarkeGeobucket2 superfluous, so it was removed.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:34 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 1eab165fc0b4d94a679f5f761d533ec3656e21d1
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Tue Sep 3 15:57:08 2013 +0200
Replaced the interface and implementation of PolyHashTable with the better hash table from BjarkeGeobucket2. That made BjarkeGeobucket2 superfluous, so it was removed.
---
Makefile.am | 3 +-
build/vs12/mathicgb-lib/mathicgb-lib.vcxproj | 2 -
.../vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters | 6 -
src/mathicgb.cpp | 2 +-
src/mathicgb/BjarkeGeobucket2.cpp | 371 ---------------------
src/mathicgb/BjarkeGeobucket2.hpp | 14 -
src/mathicgb/F4Reducer.cpp | 2 +-
src/mathicgb/MonoMonoid.hpp | 2 +-
src/mathicgb/Poly.hpp | 12 +
src/mathicgb/PolyHashTable.cpp | 238 -------------
src/mathicgb/PolyHashTable.hpp | 286 +++++++++++++---
src/mathicgb/Reducer.cpp | 16 +-
src/mathicgb/Reducer.hpp | 2 -
src/mathicgb/ReducerHash.hpp | 69 ++--
src/mathicgb/ReducerHashPack.hpp | 55 +--
src/test/gb-test.cpp | 209 ++++++------
src/test/pict.in | 2 +-
17 files changed, 416 insertions(+), 875 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 5b19c25..bf38d98 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,8 +13,7 @@ libmathicgb_la_LIBADD= $(DEPS_LIBS)
# the sources that are built to make libmathicgb. Listing the headers in
# sources ensure that those files are included in distributions.
-libmathicgb_la_SOURCES = src/mathicgb/BjarkeGeobucket2.cpp \
- src/mathicgb/BjarkeGeobucket2.hpp src/mathicgb/ClassicGBAlg.cpp \
+libmathicgb_la_SOURCES = src/mathicgb/ClassicGBAlg.cpp \
src/mathicgb/ClassicGBAlg.hpp src/mathicgb/ChainedHashTable.cpp \
src/mathicgb/ChainedHashTable.hpp src/mathicgb/MonoLookup.hpp \
src/mathicgb/MonoLookup.cpp src/mathicgb/StaticMonoMap.hpp \
diff --git a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
index 541cb6a..6ed00ae 100755
--- a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
+++ b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
@@ -441,7 +441,6 @@
<ItemGroup>
<ClCompile Include="..\..\..\src\mathicgb.cpp" />
<ClCompile Include="..\..\..\src\mathicgb\Basis.cpp" />
- <ClCompile Include="..\..\..\src\mathicgb\BjarkeGeobucket2.cpp" />
<ClCompile Include="..\..\..\src\mathicgb\CFile.cpp" />
<ClCompile Include="..\..\..\src\mathicgb\ChainedHashTable.cpp" />
<ClCompile Include="..\..\..\src\mathicgb\ClassicGBAlg.cpp" />
@@ -477,7 +476,6 @@
<ClInclude Include="..\..\..\src\mathicgb.h" />
<ClInclude Include="..\..\..\src\mathicgb\Atomic.hpp" />
<ClInclude Include="..\..\..\src\mathicgb\Basis.hpp" />
- <ClInclude Include="..\..\..\src\mathicgb\BjarkeGeobucket2.hpp" />
<ClInclude Include="..\..\..\src\mathicgb\CFile.hpp" />
<ClInclude Include="..\..\..\src\mathicgb\ChainedHashTable.hpp" />
<ClInclude Include="..\..\..\src\mathicgb\ClassicGBAlg.hpp" />
diff --git a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
index 4e35a20..4f8f7cd 100755
--- a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
+++ b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
@@ -11,9 +11,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
- <ClCompile Include="..\..\..\src\mathicgb\BjarkeGeobucket2.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
<ClCompile Include="..\..\..\src\mathicgb\ChainedHashTable.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -112,9 +109,6 @@
</ClCompile>
</ItemGroup>
<ItemGroup>
- <ClInclude Include="..\..\..\src\mathicgb\BjarkeGeobucket2.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="..\..\..\src\mathicgb\ChainedHashTable.hpp">
<Filter>Header Files</Filter>
</ClInclude>
diff --git a/src/mathicgb.cpp b/src/mathicgb.cpp
index 406db27..a56a8ea 100755
--- a/src/mathicgb.cpp
+++ b/src/mathicgb.cpp
@@ -884,7 +884,7 @@ namespace mgbi {
Reducer::ReducerType reducerType;
switch (conf.reducer()) {
case GConf::ClassicReducer:
- reducerType = Reducer::Reducer_BjarkeGeo;
+ reducerType = Reducer::Reducer_Geobucket_Hashed;
break;
default:
diff --git a/src/mathicgb/BjarkeGeobucket2.cpp b/src/mathicgb/BjarkeGeobucket2.cpp
deleted file mode 100755
index 9bebd1e..0000000
--- a/src/mathicgb/BjarkeGeobucket2.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
-// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
-#include "stdinc.h"
-#include "BjarkeGeobucket2.hpp"
-
-#include "TypicalReducer.hpp"
-#include "PolyHashTable.hpp"
-#include <mathic.h>
-
-MATHICGB_NAMESPACE_BEGIN
-
-class MonoMap {
-public:
- typedef PolyRing::Monoid Monoid;
- typedef Monoid::ConstMonoRef ConstMonoRef;
- typedef Monoid::MonoRef MonoRef;
- typedef coefficient Value;
-
- class Node {
- public:
- ConstMonoRef mono() const {return *Monoid::toMonoPtr(mMono);}
- MonoRef mono() {return *Monoid::toMonoPtr(mMono);}
-
- Value& value() {return mValue;}
- const Value& value() const {return mValue;}
-
- private:
- friend class MonoMap;
-
- Node*& next() {return mNext;}
- Node* next() const {return mNext;}
-
- Node* mNext;
- Value mValue;
- exponent mMono[1];
- };
-
- // Construct a hash table with at least requestedBucketCount buckets. There
- // may be more buckets. Currently the number is rounded up to the next power
- // of two.
- MonoMap(
- const size_t requestedBucketCount,
- const PolyRing& ring
- ):
- mHashToIndexMask(computeHashMask(requestedBucketCount)),
- mBuckets
- (make_unique_array<Node*>(hashMaskToBucketCount(mHashToIndexMask))),
- mRing(ring),
- mNodes(sizeofNode(ring)
- ),
- mSize()
- {
- std::fill_n(mBuckets.get(), bucketCount(), nullptr);
- }
-
- const PolyRing::Monoid& monoid() const {return mRing.monoid();}
-
- void rehash(const size_t requestedBucketCount) {
- const auto newHashToIndexMask = computeHashMask(requestedBucketCount);
- const auto newBucketCount = hashMaskToBucketCount(newHashToIndexMask);
- auto newBuckets = make_unique_array<Node*>(newBucketCount);
- std::fill_n(newBuckets.get(), newBucketCount, nullptr);
-
- const auto bucketsEnd = mBuckets.get() + bucketCount();
- for (auto bucket = mBuckets.get(); bucket != bucketsEnd; ++bucket) {
- for (auto node = *bucket; node != 0;) {
- const auto hash = monoid().hash(node->mono());
- const auto newIndex = hashToIndex(hash, newHashToIndexMask);
- const auto next = node->next();
- node->next() = newBuckets[newIndex];
- newBuckets[newIndex] = node;
- node = next;
- }
- }
-
- mHashToIndexMask = newHashToIndexMask;
- mBuckets = std::move(newBuckets);
- }
-
- /// Return how many buckets the hash table has.
- size_t bucketCount() const {
- return hashMaskToBucketCount(mHashToIndexMask);
- }
-
- /// Return the number of elements (not the number of buckets).
- size_t size() const {return mSize;}
-
- MATHICGB_INLINE
- std::pair<Node*, bool> insertProduct(ConstMonoRef a, ConstMonoRef b) {
- auto newNode = new (mNodes.alloc()) Node();
- monoid().multiply(a, b, newNode->mono());
- const auto abHash = monoid().hash(newNode->mono());
- auto& bucket = mBuckets[hashToIndex(abHash)];
-
- for (auto node = bucket; node != nullptr; node = node->next()) {
- if (abHash != monoid().hash(node->mono()))
- continue;
- if (monoid().equal(newNode->mono(), node->mono())) {
- mNodes.free(newNode);
- return std::make_pair(node, false); // found a*b.
- }
- }
-
- mRing.coefficientSet(newNode->value(), 0);
- newNode->next() = bucket;
- bucket = newNode;
- ++mSize;
- return std::make_pair(newNode, true); // inserted mono
- }
-
- MATHICGB_INLINE
- void remove(Node* nodeToRemove) {
- MATHICGB_ASSERT(nodeToRemove != 0);
- MATHICGB_ASSERT(mNodes.fromPool(nodeToRemove));
- const auto index = hashToIndex(monoid().hash(nodeToRemove->mono()));
- auto nodePtr = &mBuckets[index];
- while (*nodePtr != nodeToRemove) {
- MATHICGB_ASSERT(*nodePtr != nullptr);
- nodePtr = &(*nodePtr)->next();
- }
- *nodePtr = nodeToRemove->next();
- mNodes.free(nodeToRemove);
- --mSize;
- }
-
- /// Removes all elements and optimizes internal resources. This is
- /// fast if there are no elements, so if you know that there are no
- /// elements and that many operations have happened since the last clear,
- /// then call clear for better cache performance. If there is even one
- /// element, then this takes linear time in the number of buckets.
- void clear() {
- if (!empty()) {
- std::fill_n(mBuckets.get(), bucketCount(), nullptr);
- mSize = 0;
- }
- mNodes.freeAllBuffers();
- }
-
- bool empty() const {return mSize == 0;}
-
-private:
- static HashValue computeHashMask(const size_t requestedBucketCount) {
- // round request up to nearest power of 2.
- size_t pow2 = 1;
- while (pow2 < requestedBucketCount && 2 * pow2 != 0)
- pow2 *= 2;
- MATHICGB_ASSERT(pow2 > 0 && (pow2 & (pow2 - 1)) == 0); // power of two
-
- // If casting to a hash value overflows, then we get the maximum
- // possible number of buckets based on the range of the hash
- // value type. Only unsigned overflow is defined, so we need
- // to assert that the hash type is unsigned.
- static_assert(!std::numeric_limits<HashValue>::is_signed, "");
- const auto hashToIndexMask = static_cast<HashValue>(pow2 - 1);
- MATHICGB_ASSERT(pow2 == hashMaskToBucketCount(hashToIndexMask));
- return hashToIndexMask;
- }
-
- static size_t hashMaskToBucketCount(const HashValue mask) {
- const auto count = static_cast<size_t>(mask) + 1u; // should be power of 2
- MATHICGB_ASSERT(count > 0 && (count & (count - 1)) == 0);
- return count;
- }
-
- static size_t sizeofNode(const PolyRing& ring) {
- return
- sizeof(Node) +
- sizeof(Value) -
- sizeof(exponent) +
- ring.maxMonomialByteSize();
- }
-
- size_t hashToIndex(const HashValue hash) const {
- const auto index = hashToIndex(hash, mHashToIndexMask);
- MATHICGB_ASSERT(index == hash % bucketCount());
- return index;
- }
-
- static size_t hashToIndex(const HashValue hash, const HashValue mask) {
- return hash & mask;
- }
-
- HashValue mHashToIndexMask;
- std::unique_ptr<Node*[]> mBuckets;
- const PolyRing& mRing;
- memt::BufferPool mNodes;
- size_t mSize;
-};
-
-
-class BjarkeGeobucket2 : public TypicalReducer {
-public:
- BjarkeGeobucket2(const PolyRing& ring):
- mRing(ring),
- mMap(10000, ring),
- mQueue2(QueueConfiguration2(ring.monoid()))
- {}
-
- virtual std::string description() const {return "bjarke geo buckets";}
-
- void insertTail(const_term multiplier, const Poly *g1) {
- MATHICGB_ASSERT(g1 != 0);
- MATHICGB_ASSERT(g1->termsAreInDescendingOrder());
-
- if (g1->nTerms() <= 1)
- return;
-
- mNodesTmp.clear();
- auto it = g1->begin();
- const auto end = g1->end();
- for (++it; it != end; ++it) {
- coefficient prod;
- mRing.coefficientMult(it.getCoefficient(), multiplier.coeff, prod);
- auto p = mMap.insertProduct(it.getMonomial(), multiplier.monom);
- mRing.coefficientAddTo(p.first->value(), prod);
- if (p.second)
- mNodesTmp.emplace_back(p.first);
- }
- if (!mNodesTmp.empty())
- mQueue2.push(mNodesTmp.begin(), mNodesTmp.end());
- }
-
- void insert(monomial multiplier, const Poly *g1) {
- MATHICGB_ASSERT(g1 != 0);
- MATHICGB_ASSERT(g1->termsAreInDescendingOrder());
-
- mNodesTmp.clear();
- const auto end = g1->end();
- for (auto it = g1->begin(); it != end; ++it) {
- auto p = mMap.insertProduct(it.getMonomial(), multiplier);
- mRing.coefficientAddTo(p.first->value(), it.getCoefficient());
- if (p.second)
- mNodesTmp.emplace_back(p.first);
- }
- if (!mNodesTmp.empty())
- mQueue2.push(mNodesTmp.begin(), mNodesTmp.end());
- }
-
- virtual bool leadTerm(const_term& result) {
- while (!mQueue2.empty()) {
- const auto node = mQueue2.top();
- if (node->value() != 0) {
- result.coeff = node->value();
- result.monom = Monoid::toOld(node->mono());
- return true;
- }
- mQueue2.pop();
- mMap.remove(node);
- }
- return false;
- }
-
- virtual void removeLeadTerm() {
- MATHICGB_ASSERT(!mQueue2.empty());
- const auto node = mQueue2.top();
- mQueue2.pop();
- mMap.remove(node);
- }
-
- virtual size_t getMemoryUse() const {
- size_t result = TypicalReducer::getMemoryUse();
- //result += mMap.getMemoryUse();
- return result;
- }
-
-
-protected:
- void resetReducer() {
- const_term t;
- while (!mQueue2.empty()) {
- const auto node = mQueue2.top();
- mQueue2.pop();
- mMap.remove(node);
- }
- MATHICGB_ASSERT(mMap.empty());
- MATHICGB_ASSERT(mQueue2.empty());
- mMap.clear();
- }
-
-private:
- class QueueConfiguration {
- public:
- typedef PolyRing::Monoid Monoid;
-
- QueueConfiguration(const Monoid& monoid):
- mMonoid(monoid), geoBase(4), minBucketSize(1) {}
-
- typedef PolyHashTable::node* Entry;
-
- typedef bool CompareResult;
- CompareResult compare(const Entry& a, const Entry& b) const {
- return mMonoid.lessThan(a->mono(), b->mono());
- }
- bool cmpLessThan(CompareResult r) const {return r;}
-
- static const bool supportDeduplication = false;
- bool cmpEqual(CompareResult r) const {
- MATHICGB_ASSERT(false); // Not supposed to be used.
- return false;
- }
- Entry deduplicate(const Entry& a, const Entry& /* b */) const {
- MATHICGB_ASSERT(false); // Not supposed to be used.
- return a;
- }
-
- static const bool minBucketBinarySearch = true;
- static const bool trackFront = true;
- static const bool premerge = false;
- static const bool collectMax = false;
- static const mic::GeobucketBucketStorage bucketStorage =
- static_cast<mic::GeobucketBucketStorage>(1);
- static const size_t insertFactor = 1;
-
- const size_t geoBase;
- const size_t minBucketSize;
-
- private:
- const Monoid& mMonoid;
- };
-
- class QueueConfiguration2 {
- public:
- typedef PolyRing::Monoid Monoid;
-
- QueueConfiguration2(const Monoid& monoid):
- mMonoid(monoid), geoBase(4), minBucketSize(1) {}
-
- typedef MonoMap::Node* Entry;
-
- typedef bool CompareResult;
- CompareResult compare(const Entry& a, const Entry& b) const {
- return mMonoid.lessThan(a->mono(), b->mono());
- }
- bool cmpLessThan(CompareResult r) const {return r;}
-
- static const bool supportDeduplication = false;
- bool cmpEqual(CompareResult r) const {
- MATHICGB_ASSERT(false); // Not supposed to be used.
- return false;
- }
- Entry deduplicate(const Entry& a, const Entry& /* b */) const {
- MATHICGB_ASSERT(false); // Not supposed to be used.
- return a;
- }
-
- static const bool minBucketBinarySearch = true;
- static const bool trackFront = true;
- static const bool premerge = false;
- static const bool collectMax = false;
- static const mic::GeobucketBucketStorage bucketStorage =
- static_cast<mic::GeobucketBucketStorage>(1);
- static const size_t insertFactor = 1;
-
- const size_t geoBase;
- const size_t minBucketSize;
-
- private:
- const Monoid& mMonoid;
- };
-
- mutable std::vector<MonoMap::Node*> mNodesTmp;
- const PolyRing& mRing;
- MonoMap mMap;
- mic::Geobucket<QueueConfiguration2> mQueue2;
-};
-
-std::unique_ptr<TypicalReducer> makeBjarkeGeobucket2(const PolyRing& ring) {
- return make_unique<BjarkeGeobucket2>(ring);
-}
-
-MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/BjarkeGeobucket2.hpp b/src/mathicgb/BjarkeGeobucket2.hpp
deleted file mode 100755
index eaffe5c..0000000
--- a/src/mathicgb/BjarkeGeobucket2.hpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
-// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
-#ifndef MATHICGB_BJARKE_GEOBUCKET2_GUARD
-#define MATHICGB_BJARKE_GEOBUCKET2_GUARD
-
-MATHICGB_NAMESPACE_BEGIN
-
-class TypicalReducer;
-class PolyRing;
-
-std::unique_ptr<TypicalReducer> makeBjarkeGeobucket2(const PolyRing& ring);
-
-MATHICGB_NAMESPACE_END
-#endif
diff --git a/src/mathicgb/F4Reducer.cpp b/src/mathicgb/F4Reducer.cpp
index 023b914..360b74d 100755
--- a/src/mathicgb/F4Reducer.cpp
+++ b/src/mathicgb/F4Reducer.cpp
@@ -47,7 +47,7 @@ MATHICGB_NAMESPACE_BEGIN
F4Reducer::F4Reducer(const PolyRing& ring, Type type):
mType(type),
- mFallback(Reducer::makeReducer(Reducer::Reducer_BjarkeGeo, ring)),
+ mFallback(Reducer::makeReducer(Reducer::Reducer_Geobucket_Hashed, ring)),
mRing(ring),
mMemoryQuantum(0),
mStoreToFile(""),
diff --git a/src/mathicgb/MonoMonoid.hpp b/src/mathicgb/MonoMonoid.hpp
index c2aa125..def8cb3 100755
--- a/src/mathicgb/MonoMonoid.hpp
+++ b/src/mathicgb/MonoMonoid.hpp
@@ -1561,7 +1561,7 @@ private:
friend class MonoVector;
friend class MonoPool;
- friend class MonoMap;
+ friend class PolyHashTable;
typedef typename Base::Gradings Gradings;
diff --git a/src/mathicgb/Poly.hpp b/src/mathicgb/Poly.hpp
index 81ca69c..45ee1af 100755
--- a/src/mathicgb/Poly.hpp
+++ b/src/mathicgb/Poly.hpp
@@ -48,6 +48,12 @@ public:
reference operator*() const {
return std::pair<coefficient&, monomial>(getCoefficient(), getMonomial());
}
+ const_term term() const {
+ const_term t;
+ t.monom = getMonomial();
+ t.coeff = getCoefficient();
+ return t;
+ }
};
class const_iterator {
@@ -77,6 +83,12 @@ public:
return std::pair<coefficient, const_monomial>
(getCoefficient(), getMonomial());
}
+ const_term term() const {
+ const_term t;
+ t.monom = getMonomial();
+ t.coeff = getCoefficient();
+ return t;
+ }
};
void sortTermsDescending();
diff --git a/src/mathicgb/PolyHashTable.cpp b/src/mathicgb/PolyHashTable.cpp
index d111b19..563cd0e 100755
--- a/src/mathicgb/PolyHashTable.cpp
+++ b/src/mathicgb/PolyHashTable.cpp
@@ -9,244 +9,6 @@
MATHICGB_NAMESPACE_BEGIN
-PolyHashTable::PolyHashTable(const PolyRing *R, int nbits)
- : mRing(*R),
- mHashMask((static_cast<size_t>(1) << nbits)-1),
- mTableSize(static_cast<size_t>(1) << nbits),
- mLogTableSize(nbits),
- mNodeCount(0),
- mBinCount(0),
- mMaxCountBeforeRebuild(0)
-{
- mHashTable.resize(mTableSize);
- mMonomialSize = R->maxMonomialSize() * sizeof(exponent);
- // set each entry of mHashTable to null
-
- reset();
-}
-
-void PolyHashTable::reset()
-{
- // The following no longer needs to be done
-
- // Clear the table, and memory areas.
-
-#if 0
- MATHICGB_ASSERT(mNodeCount != 0);
- for (size_t count = 0; count < mTableSize; ++count)
- {
- if ( mHashTable[count] != 0)
- std::cerr << "error: hash table is not zero on reset" << std::endl;
- }
-#endif
-
- mArena.freeAllAllocs();
-
- mBinCount = 0;
- mNodeCount = 0;
-}
-
-void PolyHashTable::resize(size_t new_nbits)
-// Don't change the nodes, table, but do recreate mHashTable
-{
- // Make a new vector of node *'s.
- // swap the two.
- // Loop through each one, reinserting the node into the proper bin.
-
- // std::cout << "resizing PolyHashTable to " << new_nbits << " bits" << " count=" << mNodeCount << std::endl;
- size_t const old_table_size = mTableSize;
- mTableSize = static_cast<size_t>(1) << new_nbits;
- mLogTableSize = new_nbits;
- mHashMask = mTableSize-1;
- MonomialArray old_table(mTableSize);
-
- std::swap(old_table, mHashTable);
- mBinCount = 0;
- for (size_t i = 0; i < old_table_size; ++i)
- {
- node *p = old_table[i];
- while (p != 0)
- {
- node *q = p;
- p = p->next();
- q->next() = 0;
- // Reinsert node. We know that it is unique
- const_monomial m = q->monom;
- size_t hashval = mRing.monomialHashValue(m) & mHashMask;
- node *r = mHashTable[hashval];
- if (r == 0)
- {
- mBinCount++;
- q->next() = r;
- mHashTable[hashval] = q;
- }
- else
- {
- // put it at the end
- for ( ; r->next() != 0; r = r->next()) { }
- r->next() = q;
- }
- }
- }
-
- // todo: consider if this can overflow or something else nasty might happen
- const double threshold = 0.1;
- mMaxCountBeforeRebuild =
- static_cast<size_t>(std::floor(mTableSize * threshold));
-}
-
-PolyHashTable::node * PolyHashTable::makeNode(coefficient coeff, const_monomial monom)
-{
- mNodeCount++;
- node *q = static_cast<node *>(mArena.allocObjectNoCon<node>());
- q->next() = 0;
- q->monom = monom;
- mRing.coefficientSet(q->coeff, coeff);
- return q;
-}
-
-bool PolyHashTable::lookup_and_insert(const_monomial m, coefficient val, node *& result)
-// Returns true if m is in the table, else inserts m into the hash table (as is, without copying it)
-{
- size_t fullHashVal = mRing.monomialHashValue(m);
- size_t hashval = fullHashVal & mHashMask;
-
- MATHICGB_ASSERT(hashval < mHashTable.size());
- node *tmpNode = mHashTable[hashval];
- if (tmpNode == 0) {
- result = makeNode(val, m);
- mHashTable[hashval] = result;
- } else {
- while (true) {
- if (mRing.monomialHashValue(tmpNode->monom) == fullHashVal && mRing.monomialEQ(m, tmpNode->monom)) {
- mRing.coefficientAddTo(tmpNode->coeff, val);
- result = tmpNode;
- return true;
- }
- if (tmpNode->next() == 0) {
- result = makeNode(val, m);
- tmpNode->next() = result;
- break;
- }
- tmpNode = tmpNode->next();
- }
- }
-
- if (mNodeCount > mMaxCountBeforeRebuild)
- resize(mLogTableSize + 2); // increase by a factor of 4??
-
- return false;
-}
-
-void PolyHashTable::insert(
- Poly::const_iterator first,
- Poly::const_iterator last,
- MonomialArray &result
-) {
- for (auto i = first; i != last; ++i) {
- monomial monomspace = mRing.allocMonomial(mArena);
- node* p;
- mRing.monomialCopy(i.getMonomial(), monomspace);
- bool found = lookup_and_insert(monomspace, i.getCoefficient(), p);
- if (found)
- mRing.freeTopMonomial(mArena,monomspace);
- else
- result.push_back(p);
- }
-}
-
-void PolyHashTable::insert(
- const_term multiplier,
- Poly::const_iterator first,
- Poly::const_iterator last,
- MonomialArray &result
-) {
- for (auto i = first; i != last; ++i) {
- monomial monomspace = mRing.allocMonomial(mArena);
- coefficient c;
- mRing.coefficientSet(c, multiplier.coeff);
- node* p;
- mRing.monomialMult(multiplier.monom, i.getMonomial(), monomspace);
- mRing.coefficientMultTo(c, i.getCoefficient());
- bool found = lookup_and_insert(monomspace, c, p);
- if (found)
- mRing.freeTopMonomial(mArena,monomspace);
- else
- result.push_back(p);
- }
-}
-
-void PolyHashTable::insert(
- const_monomial multiplier,
- Poly::const_iterator first,
- Poly::const_iterator last,
- MonomialArray& result
-) {
- for (Poly::const_iterator i = first; i != last; ++i) {
- monomial monomspace = mRing.allocMonomial(mArena);
- node* p;
- mRing.monomialMult(multiplier, i.getMonomial(), monomspace);
- bool found = lookup_and_insert(monomspace, i.getCoefficient(), p);
- if (found)
- mRing.freeTopMonomial(mArena,monomspace);
- else
- result.push_back(p);
- }
-}
-
-std::pair<bool, PolyHashTable::node*>
-PolyHashTable::insert(const_term termToInsert) {
- node* n;
- bool alreadyInThere = lookup_and_insert
- (termToInsert.monom, termToInsert.coeff, n);
- return std::make_pair(!alreadyInThere, n);
-}
-
-void PolyHashTable::unlink(node* p)
-{
- mNodeCount--;
- size_t const hashval = mRing.monomialHashValue(p->monom) & mHashMask;
-
- node head;
- node* tmpNode = mHashTable[hashval];
- head.next() = tmpNode;
- for (node* q = &head; q->next() != 0; q = q->next()) {
- if (q->next() == p) {
- q->next() = p->next();
- mHashTable[hashval] = head.next();
- return;
- }
- }
- // If we get here, then the node is not at its supposed hash value.
- // That probably means either that the node has been deleted twice
- // or that the value in the node changed so that its hash value
- // changed. That is not allowed.
- MATHICGB_ASSERT(false);
-}
-
-void PolyHashTable::remove(node* n) {
- unlink(n);
-}
-
-bool PolyHashTable::popTerm(node *p, coefficient &result_coeff, const_monomial &result_monom)
-{
- unlink(p);
- if (!mRing.coefficientIsZero(p->coeff))
- {
- result_coeff = p->coeff;
- result_monom = p->monom;
- return true;
- }
- return false;
-}
-
-size_t PolyHashTable::getMemoryUse() const
-{
- size_t result = mHashTable.capacity() * sizeof(node *);
- result += mArena.getMemoryUse();
- return result;
-}
-
MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PolyHashTable.hpp b/src/mathicgb/PolyHashTable.hpp
index 9c4127f..5040ed0 100755
--- a/src/mathicgb/PolyHashTable.hpp
+++ b/src/mathicgb/PolyHashTable.hpp
@@ -11,6 +11,211 @@
MATHICGB_NAMESPACE_BEGIN
+class PolyHashTable {
+public:
+ typedef PolyRing::Monoid Monoid;
+ typedef Monoid::ConstMonoRef ConstMonoRef;
+ typedef Monoid::MonoRef MonoRef;
+ typedef coefficient Value;
+
+ class Node {
+ public:
+ ConstMonoRef mono() const {return *Monoid::toMonoPtr(mMono);}
+ MonoRef mono() {return *Monoid::toMonoPtr(mMono);}
+
+ Value& value() {return mValue;}
+ const Value& value() const {return mValue;}
+
+ private:
+ friend class PolyHashTable;
+
+ Node*& next() {return mNext;}
+ Node* next() const {return mNext;}
+
+ Node* mNext;
+ Value mValue;
+ exponent mMono[1];
+ };
+
+ // Construct a hash table with at least requestedBucketCount buckets. There
+ // may be more buckets. Currently the number is rounded up to the next power
+ // of two.
+ PolyHashTable(const PolyRing& ring):
+ mHashToIndexMask(computeHashMask(1000)),
+ mBuckets
+ (make_unique_array<Node*>(hashMaskToBucketCount(mHashToIndexMask))),
+ mRing(ring),
+ mNodes(sizeofNode(ring)
+ ),
+ mSize()
+ {
+ mMaxSize = static_cast<size_t>(bucketCount() * maxLoadFactor());
+ std::fill_n(mBuckets.get(), bucketCount(), nullptr);
+ }
+
+ const PolyRing::Monoid& monoid() const {return mRing.monoid();}
+
+ /// Return how many buckets the hash table has.
+ size_t bucketCount() const {
+ return hashMaskToBucketCount(mHashToIndexMask);
+ }
+
+ /// Return the number of elements (not the number of buckets).
+ size_t size() const {return mSize;}
+
+ MATHICGB_INLINE
+ std::pair<Node*, bool> insertProduct(ConstMonoRef a, ConstMonoRef b) {
+ auto newNode = new (mNodes.alloc()) Node();
+ monoid().multiply(a, b, newNode->mono());
+ const auto abHash = monoid().hash(newNode->mono());
+ auto& bucket = mBuckets[hashToIndex(abHash)];
+
+ for (auto node = bucket; node != nullptr; node = node->next()) {
+ if (abHash != monoid().hash(node->mono()))
+ continue;
+ if (monoid().equal(newNode->mono(), node->mono())) {
+ mNodes.free(newNode);
+ return std::make_pair(node, false); // found a*b.
+ }
+ }
+
+ mRing.coefficientSet(newNode->value(), 0);
+ newNode->next() = bucket;
+ bucket = newNode;
+ ++mSize;
+ if (mSize >= mMaxSize)
+ rehash(bucketCount() * 2);
+ return std::make_pair(newNode, true); // inserted mono
+ }
+
+ MATHICGB_INLINE
+ std::pair<Node*, bool> insertProduct
+ (ConstMonoRef a, ConstMonoRef b, Value add)
+ {
+ auto p = insertProduct(a, b);
+ mRing.coefficientAddTo(p.first->value(), add);
+ return p;
+ }
+
+ MATHICGB_INLINE
+ std::pair<Node*, bool> insertProduct(const_term a, const_term b)
+ {
+ Value prod;
+ mRing.coefficientMult(a.coeff, b.coeff, prod);
+ return insertProduct(a.monom, b.monom, prod);
+ }
+
+ MATHICGB_INLINE
+ void remove(Node* nodeToRemove) {
+ MATHICGB_ASSERT(nodeToRemove != 0);
+ MATHICGB_ASSERT(mNodes.fromPool(nodeToRemove));
+ const auto index = hashToIndex(monoid().hash(nodeToRemove->mono()));
+ auto nodePtr = &mBuckets[index];
+ while (*nodePtr != nodeToRemove) {
+ MATHICGB_ASSERT(*nodePtr != nullptr);
+ nodePtr = &(*nodePtr)->next();
+ }
+ *nodePtr = nodeToRemove->next();
+ mNodes.free(nodeToRemove);
+ --mSize;
+ }
+
+ /// Removes all elements and optimizes internal resources. This is
+ /// fast if there are no elements, so if you know that there are no
+ /// elements and that many operations have happened since the last clear,
+ /// then call clear for better cache performance. If there is even one
+ /// element, then this takes linear time in the number of buckets.
+ void clear() {
+ if (!empty()) {
+ std::fill_n(mBuckets.get(), bucketCount(), nullptr);
+ mSize = 0;
+ }
+ mNodes.freeAllBuffers();
+ }
+
+ bool empty() const {return mSize == 0;}
+
+ size_t getMemoryUse() const {
+ return bucketCount() * sizeof(mBuckets[0]) + mNodes.getMemoryUse();
+ }
+
+private:
+ void rehash(const size_t requestedBucketCount) {
+ const auto newHashToIndexMask = computeHashMask(requestedBucketCount);
+ const auto newBucketCount = hashMaskToBucketCount(newHashToIndexMask);
+ auto newBuckets = make_unique_array<Node*>(newBucketCount);
+ std::fill_n(newBuckets.get(), newBucketCount, nullptr);
+
+ const auto bucketsEnd = mBuckets.get() + bucketCount();
+ for (auto bucket = mBuckets.get(); bucket != bucketsEnd; ++bucket) {
+ for (auto node = *bucket; node != 0;) {
+ const auto hash = monoid().hash(node->mono());
+ const auto newIndex = hashToIndex(hash, newHashToIndexMask);
+ const auto next = node->next();
+ node->next() = newBuckets[newIndex];
+ newBuckets[newIndex] = node;
+ node = next;
+ }
+ }
+
+ mHashToIndexMask = newHashToIndexMask;
+ mBuckets = std::move(newBuckets);
+ mMaxSize = static_cast<size_t>(bucketCount() * maxLoadFactor());
+ }
+
+ static HashValue computeHashMask(const size_t requestedBucketCount) {
+ // round request up to nearest power of 2.
+ size_t pow2 = 1;
+ while (pow2 < requestedBucketCount && 2 * pow2 != 0)
+ pow2 *= 2;
+ MATHICGB_ASSERT(pow2 > 0 && (pow2 & (pow2 - 1)) == 0); // power of two
+
+ // If casting to a hash value overflows, then we get the maximum
+ // possible number of buckets based on the range of the hash
+ // value type. Only unsigned overflow is defined, so we need
+ // to assert that the hash type is unsigned.
+ static_assert(!std::numeric_limits<HashValue>::is_signed, "");
+ const auto hashToIndexMask = static_cast<HashValue>(pow2 - 1);
+ MATHICGB_ASSERT(pow2 == hashMaskToBucketCount(hashToIndexMask));
+ return hashToIndexMask;
+ }
+
+ static size_t hashMaskToBucketCount(const HashValue mask) {
+ const auto count = static_cast<size_t>(mask) + 1u; // should be power of 2
+ MATHICGB_ASSERT(count > 0 && (count & (count - 1)) == 0);
+ return count;
+ }
+
+ static size_t sizeofNode(const PolyRing& ring) {
+ return
+ sizeof(Node) +
+ sizeof(Value) -
+ sizeof(exponent) +
+ ring.maxMonomialByteSize();
+ }
+
+ /// The maximum allowed value of elementCount() / bucketCount().
+ static double maxLoadFactor() {return 0.10;}
+
+ size_t hashToIndex(const HashValue hash) const {
+ const auto index = hashToIndex(hash, mHashToIndexMask);
+ MATHICGB_ASSERT(index == hash % bucketCount());
+ return index;
+ }
+
+ static size_t hashToIndex(const HashValue hash, const HashValue mask) {
+ return hash & mask;
+ }
+
+ HashValue mHashToIndexMask;
+ std::unique_ptr<Node*[]> mBuckets;
+ const PolyRing& mRing;
+ memt::BufferPool mNodes;
+ size_t mSize;
+ size_t mMaxSize;
+};
+
+/*
// The hash table is a map: monomial => coeff
// Operations required on monomials:
// hash (this will currently pick out one entry of a monomial)
@@ -31,9 +236,8 @@ public:
class Node {
public:
-
- const_monomial& mono() {return monom;}
- const const_monomial& mono() const {return monom;}
+ const const_monomial& mono() {return mMonom;}
+ const const_monomial& mono() const {return mMonom;}
Value& value() {return coeff;}
const Value& value() const {return coeff;}
@@ -46,61 +250,51 @@ public:
Node* mNext;
coefficient coeff;
- const_monomial monom;
+ const_monomial mMonom;
};
- typedef Node node; // todo: remove
-
- typedef std::vector<node*> MonomialArray;
- PolyHashTable(const PolyRing *R, int nbits);
+ PolyHashTable(const PolyRing& ring);
- std::string description() const {return "polynomial hash table";}
- void reset(); // Clear the table, and memory areas.
+ const Monoid& monoid() const {return mRing.monoid();}
- void resize(size_t new_nbits); // Don't change the nodes, table, but do recreate hashtable_
+ std::pair<Node*, bool> insertProduct
+ (ConstMonoRef a, ConstMonoRef b);
- size_t getMemoryUse() const;
+ std::pair<Node*, bool> insertProduct
+ (ConstMonoRef a, ConstMonoRef b, Value add)
+ {
+ auto p = insertProduct(a, b);
+ mRing.coefficientAddTo(p.first->value(), add);
+ return p;
+ }
- //@ insert multiplier * g: any monomials already in the hash table are removed,
- // but their field coefficients in the table are modified accordingly.
- // Resulting pointers to 'node's are placed, in order, into result.
- void insert(Poly::const_iterator first,
- Poly::const_iterator last,
- MonomialArray &result);
- void insert(const_term multiplier,
- Poly::const_iterator first,
- Poly::const_iterator last,
- MonomialArray &result);
- void insert(const_monomial multiplier,
- Poly::const_iterator first,
- Poly::const_iterator last,
- MonomialArray &result);
-
- // Inserts t into the hashtable. Returns true if there is not already
- // a node with the monomial t.monom. If there is already such a node,
- // then t.coeff is added to the coefficient of that node. In either case,
- // node will point to the node for t.monom. The original value of
- // nodeOut is not used.
- std::pair<bool, node*> insert(const_term termToInsert);
+ std::pair<Node*, bool> insertProduct(const_term a, const_term b)
+ {
+ Value prod;
+ mRing.coefficientMult(a.coeff, b.coeff, prod);
+ return insertProduct(a.monom, b.monom, prod);
+ }
// Removes the node from the hash table.
- void remove(node* n);
+ void remove(Node* n);
+
+ void clear(); // Clear the table, and memory areas.
- // deprecated: use remove instead
- // popTerm removes 'p' from the hash table, setting result_coeff and result_monom if the coefficient is not zero.
- // result_monom is set with a pointer into monomial space in this class, so will only
- // be valid until a 'reset' is called.
- bool popTerm(node *p, coefficient &result_coeff, const_monomial &result_monom);
+ bool empty() const {return mNodeCount == 0;}
-protected:
- node * makeNode(coefficient coeff, const_monomial monom);
- void unlink(node *p);
- bool lookup_and_insert(const_monomial m, coefficient val, node *&result);
+ size_t getMemoryUse() const;
+
+private:
+ typedef std::vector<Node*> MonomialArray;
+ void resize(size_t new_nbits); // Don't change the nodes, table, but do recreate hashtable_
+
+ Node* makeNode(const_monomial monom);
+ bool lookup_and_insert(const_monomial m, Node *&result);
const PolyRing& mRing;
- std::vector<node*> mHashTable;
- size_t mHashMask; // this is the number, in binary: 00001111...1, where
+ std::vector<Node*> mHashTable;
+ HashValue mHashMask; // this is the number, in binary: 00001111...1, where
// the number of 1's is mLogTableSize
memt::Arena mArena; // space for monomials represented in this class. Also nodes??
@@ -114,6 +308,6 @@ protected:
size_t mMonomialSize;
};
-
+*/
MATHICGB_NAMESPACE_END
#endif
diff --git a/src/mathicgb/Reducer.cpp b/src/mathicgb/Reducer.cpp
index f0af4ef..0459942 100755
--- a/src/mathicgb/Reducer.cpp
+++ b/src/mathicgb/Reducer.cpp
@@ -3,7 +3,6 @@
#include "stdinc.h"
#include "Reducer.hpp"
-#include "BjarkeGeobucket2.hpp"
#include "ReducerPack.hpp"
#include "ReducerPackDedup.hpp"
#include "ReducerNoDedup.hpp"
@@ -45,9 +44,6 @@ std::unique_ptr<Reducer> Reducer::makeReducerNullOnUnknown(
PolyRing const& ring
) {
switch (type) {
- case Reducer_BjarkeGeo:
- return makeBjarkeGeobucket2(ring);
-
case Reducer_TourTree_NoDedup:
return std::unique_ptr<Reducer>(new ReducerNoDedup<mic::TourTree>(ring));
case Reducer_TourTree_Dedup:
@@ -101,8 +97,6 @@ std::unique_ptr<Reducer> Reducer::makeReducerNullOnUnknown(
Reducer::ReducerType Reducer::reducerType(int typ)
{
switch (typ) {
- case 4: return Reducer_BjarkeGeo;
-
case 7: return Reducer_TourTree_NoDedup;
case 8: return Reducer_TourTree_Dedup;
case 9: return Reducer_TourTree_Hashed;
@@ -127,21 +121,13 @@ Reducer::ReducerType Reducer::reducerType(int typ)
case 25: return Reducer_F4_Old;
case 26: return Reducer_F4_New;
- default: return Reducer_BjarkeGeo;
+ default: return Reducer_Geobucket_Hashed;
}
}
void Reducer::displayReducerTypes(std::ostream &o)
{
o << "Reducer types:" << std::endl;
- o << " 0 PolyHeap" << std::endl;
- o << " 1 PolyGeoBucket" << std::endl;
- o << " 2 Poly" << std::endl;
- o << " 3 PolyHash" << std::endl;
- o << " 4 BjarkeGeo2" << std::endl;
- o << " 5 Tournament tree" << std::endl;
- o << " 6 Hashed Tournament tree" << std::endl;
-
o << " 7 TournamentTree.NoDedup" << std::endl;
o << " 8 TournamentTree.Dedup" << std::endl;
o << " 9 TournamentTree.Hashed" << std::endl;
diff --git a/src/mathicgb/Reducer.hpp b/src/mathicgb/Reducer.hpp
index ca3efb7..f2878be 100755
--- a/src/mathicgb/Reducer.hpp
+++ b/src/mathicgb/Reducer.hpp
@@ -78,8 +78,6 @@ public:
// ***** Kinds of reducers and creating a Reducer
enum ReducerType {
- Reducer_BjarkeGeo = 4, // uses hash table on front to remove duplicates
-
Reducer_TourTree_NoDedup = 7,
Reducer_TourTree_Dedup,
Reducer_TourTree_Hashed,
diff --git a/src/mathicgb/ReducerHash.hpp b/src/mathicgb/ReducerHash.hpp
index 0568535..1244ead 100755
--- a/src/mathicgb/ReducerHash.hpp
+++ b/src/mathicgb/ReducerHash.hpp
@@ -36,16 +36,17 @@ protected:
public:
class Configuration : public ReducerHelper::PlainConfiguration {
public:
- typedef PolyHashTable::node * Entry;
+ typedef PolyHashTable::Node* Entry;
Configuration(const PolyRing& ring): PlainConfiguration(ring) {}
CompareResult compare(const Entry& a, const Entry& b) const {
- return ring().monomialLT(a->mono(), b->mono());
+ return ring().monoid().lessThan(a->mono(), b->mono());
}
};
private:
+ mutable std::vector<PolyHashTable::Node*> mNodesTmp;
const PolyRing &mRing;
PolyHashTable mHashTable;
Queue<Configuration> mQueue;
@@ -54,7 +55,7 @@ private:
template<template<typename> class Q>
ReducerHash<Q>::ReducerHash(const PolyRing &ring):
mRing(ring),
- mHashTable(&ring,10),
+ mHashTable(ring),
mQueue(Configuration(ring))
{}
@@ -67,33 +68,46 @@ void ReducerHash<Q>::insertTail(const_term multiplier, const Poly *g1)
{
if (g1->nTerms() <= 1) return;
- PolyHashTable::MonomialArray M;
- mHashTable.insert(multiplier, ++(g1->begin()), g1->end(), M);
- if (!M.empty())
- mQueue.push(M.begin(),M.end());
+ mNodesTmp.clear();
+ auto it = g1->begin();
+ const auto end = g1->end();
+ for (++it; it != end; ++it) {
+ auto p = mHashTable.insertProduct(it.term(), multiplier);
+ if (p.second)
+ mNodesTmp.emplace_back(p.first);
+ }
+ if (!mNodesTmp.empty())
+ mQueue.push(mNodesTmp.begin(), mNodesTmp.end());
}
template<template<typename> class Q>
void ReducerHash<Q>::insert(monomial multiplier, const Poly *g1)
{
- PolyHashTable::MonomialArray M;
-
- mHashTable.insert(multiplier, g1->begin(), g1->end(), M);
-
- if (!M.empty())
- mQueue.push(M.begin(),M.end());
+ mNodesTmp.clear();
+ const auto end = g1->end();
+ for (auto it = g1->begin(); it != end; ++it) {
+ auto p = mHashTable.insertProduct
+ (it.getMonomial(), multiplier, it.getCoefficient());
+ if (p.second)
+ mNodesTmp.emplace_back(p.first);
+ }
+ if (!mNodesTmp.empty())
+ mQueue.push(mNodesTmp.begin(), mNodesTmp.end());
}
template<template<typename> class Q>
-bool ReducerHash<Q>::leadTerm(const_term &result)
+bool ReducerHash<Q>::leadTerm(const_term& result)
{
- while (!mQueue.empty())
- {
- if (mHashTable.popTerm(mQueue.top(), result.coeff, result.monom))
- // returns true if mQueue.top() is not the zero element
- return true;
- mQueue.pop();
+ while (!mQueue.empty()) {
+ const auto top = mQueue.top();
+ if (!mRing.coefficientIsZero(top->value())) {
+ result.coeff = top->value();
+ result.monom = Monoid::toOld(top->mono());
+ return true;
}
+ mQueue.pop();
+ mHashTable.remove(top);
+ }
return false;
}
@@ -101,19 +115,20 @@ template<template<typename> class Q>
void ReducerHash<Q>::removeLeadTerm()
// returns true if there is a term to extract
{
+ const auto top = mQueue.top();
mQueue.pop();
+ mHashTable.remove(top);
}
template<template<typename> class Q>
void ReducerHash<Q>::resetReducer()
{
- const_term t;
- while (leadTerm(t))
- {
- mQueue.pop();
- }
- mHashTable.reset();
- // how to reset mQueue ?
+ while (!mQueue.empty()) {
+ const auto top = mQueue.top();
+ mQueue.pop();
+ mHashTable.remove(top);
+ }
+ mHashTable.clear();
}
template<template<typename> class Q>
diff --git a/src/mathicgb/ReducerHashPack.hpp b/src/mathicgb/ReducerHashPack.hpp
index 834d202..4c90880 100755
--- a/src/mathicgb/ReducerHashPack.hpp
+++ b/src/mathicgb/ReducerHashPack.hpp
@@ -43,11 +43,8 @@ private:
Poly::const_iterator pos;
Poly::const_iterator const end;
const_term const multiple;
- monomial current; // multiple.monom * pos.getMonomial()
- PolyHashTable::node* node;
+ PolyHashTable::Node* node;
- void computeCurrent(const PolyRing& ring, monomial current);
- void currentCoefficient(const PolyRing& ring, coefficient& coeff);
void destroy(const PolyRing& ring);
};
@@ -56,7 +53,7 @@ private:
typedef MultipleWithPos* Entry;
Configuration(const PolyRing& ring) : PlainConfiguration(ring) {}
CompareResult compare(const Entry& a, const Entry& b) const {
- return ring().monomialLT(a->current, b->current);
+ return ring().monoid().lessThan(a->node->mono(), b->node->mono());
}
};
@@ -74,10 +71,9 @@ template<template<typename> class Q>
ReducerHashPack<Q>::ReducerHashPack(const PolyRing& ring):
mRing(ring),
mQueue(Configuration(ring)),
- mHashTable(&ring, 10),
+ mHashTable(ring),
mPool(sizeof(MultipleWithPos))
-{
-}
+{}
template<template<typename> class Q>
class ReducerHashPack<Q>::MonomialFree
@@ -140,24 +136,10 @@ ReducerHashPack<Q>::MultipleWithPos::MultipleWithPos
pos(poly.begin()),
end(poly.end()),
multiple(allocTerm(poly.ring(), multiple)),
- current(poly.ring().allocMonomial()),
node(0) {}
template<template<typename> class Q>
-void ReducerHashPack<Q>::MultipleWithPos::
-computeCurrent(const PolyRing& ring, monomial current) {
- ring.monomialMult(multiple.monom, pos.getMonomial(), current);
-}
-
-template<template<typename> class Q>
-void ReducerHashPack<Q>::MultipleWithPos::currentCoefficient
-(const PolyRing& ring, coefficient& coeff) {
- ring.coefficientMult(multiple.coeff, pos.getCoefficient(), coeff);
-}
-
-template<template<typename> class Q>
void ReducerHashPack<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
- ring.freeMonomial(current);
ring.freeMonomial(const_cast<ConstMonomial&>(multiple.monom).castAwayConst());
// Call the destructor to destruct the iterators into std::vector.
@@ -175,7 +157,7 @@ bool ReducerHashPack<Q>::leadTerm(const_term& result) {
if (!mRing.coefficientIsZero(entry->node->value())) {
result.coeff = entry->node->value();
- result.monom = entry->node->mono();
+ result.monom = Monoid::toOld(entry->node->mono());
return true;
}
removeLeadTerm();
@@ -204,14 +186,11 @@ void ReducerHashPack<Q>::removeLeadTerm() {
mPool.free(entry);
break;
}
- term t;
- t.monom = entry->current;
- entry->computeCurrent(mRing, t.monom);
- entry->currentCoefficient(mRing, t.coeff);
-
- std::pair<bool, PolyHashTable::node*> p = mHashTable.insert(t);
- if (p.first) {
- entry->node = p.second;
+
+ const auto p = mHashTable.insertProduct
+ (entry->multiple, entry->pos.term());
+ if (p.second) {
+ entry->node = p.first;
mQueue.decreaseTop(entry);
break;
}
@@ -222,14 +201,10 @@ template<template<typename> class Q>
void ReducerHashPack<Q>::insertEntry(MultipleWithPos* entry) {
MATHICGB_ASSERT(entry != 0);
for (; entry->pos != entry->end; ++entry->pos) {
- term t;
- t.monom = entry->current;
- entry->computeCurrent(mRing, t.monom);
- entry->currentCoefficient(mRing, t.coeff);
-
- std::pair<bool, PolyHashTable::node*> p = mHashTable.insert(t);
- if (p.first) {
- entry->node = p.second;
+ const auto p = mHashTable.insertProduct
+ (entry->multiple, entry->pos.term());
+ if (p.second) {
+ entry->node = p.first;
mQueue.push(entry);
return;
}
@@ -244,7 +219,7 @@ void ReducerHashPack<Q>::resetReducer()
MonomialFree freeer(mRing);
mQueue.forAll(freeer);
mQueue.clear();
- mHashTable.reset();
+ mHashTable.clear();
}
template<template<typename> class Q>
diff --git a/src/test/gb-test.cpp b/src/test/gb-test.cpp
index 273a5bd..0e01cd0 100755
--- a/src/test/gb-test.cpp
+++ b/src/test/gb-test.cpp
@@ -51,114 +51,107 @@ void testGB(
#define MATHICGB_ESCAPE_MULTILINE_STRING(str) #str
char const allPairsTests[] = MATHICGB_ESCAPE_MULTILINE_STRING(
spairQueue reducerType divLookup monTable buchberger postponeKoszul useBaseDivisors autoTailReduce autoTopReduce preferSparseReducers useSingularCriterionEarly sPairGroupSize threadCount
-1 23 3 1 0 0 0 0 0 0 0 1 1
-2 14 1 2 0 1 1 0 0 1 1 2 2
-0 10 2 3 0 0 0 0 0 1 1 1 8
-3 23 4 4 1 0 0 1 1 1 0 100 2
-2 26 1 2 1 0 0 1 1 0 0 2 8
-3 4 4 4 0 1 1 0 0 0 1 2 1
-1 22 2 3 1 0 0 1 1 1 0 10 1
-0 17 3 1 0 1 1 0 0 0 1 10 8
-0 7 2 1 1 0 0 0 1 0 0 2 2
-1 23 4 3 0 1 1 0 0 1 1 10 8
-0 14 3 1 1 0 0 1 1 0 0 0 1
-2 18 2 2 0 1 1 0 0 0 1 100 1
-3 15 3 3 1 0 0 1 0 1 0 2 2
-3 7 1 4 0 1 1 0 0 1 1 10 8
-1 13 1 3 1 0 0 1 1 0 0 2 2
-2 12 2 4 0 1 1 0 0 1 1 0 8
-0 26 1 1 1 0 0 0 0 1 0 100 1
-1 21 4 2 1 0 0 1 0 0 0 0 2
-0 12 3 2 1 0 0 1 1 0 0 10 2
-2 8 4 1 1 0 0 0 1 1 0 2 2
-3 23 2 2 1 0 0 1 0 0 0 2 8
-2 21 3 4 0 1 1 0 0 1 1 1 1
-0 22 4 2 0 1 1 0 0 0 1 1 2
-3 26 4 3 1 0 0 1 1 1 0 0 2
-3 8 1 4 0 1 1 0 0 0 1 1 1
-0 25 1 4 1 0 0 1 1 1 0 0 1
-3 22 3 1 0 1 1 0 0 1 0 100 8
-2 20 2 3 0 0 1 0 0 0 1 1 8
-0 21 1 1 1 0 0 0 1 0 0 10 8
-1 19 3 4 1 0 0 0 1 0 0 0 8
-1 25 3 3 1 0 0 0 0 0 0 100 2
-0 15 1 4 0 1 1 0 0 0 1 100 1
-0 20 4 4 1 0 0 1 1 1 0 100 1
-2 24 1 4 0 1 0 0 0 1 1 2 1
-3 24 3 3 1 0 0 1 1 0 0 1 8
-2 10 4 2 1 0 0 1 1 0 0 100 1
-3 16 1 1 0 1 1 0 0 0 0 0 2
-3 19 1 3 0 1 1 0 0 1 1 2 2
-2 25 2 1 1 0 0 0 1 1 0 10 8
-3 12 1 3 0 0 1 0 0 1 0 1 1
-1 4 3 2 1 0 0 1 1 1 0 10 8
-1 12 4 1 0 0 1 0 0 0 1 100 8
-2 16 4 4 0 0 0 0 0 1 1 2 1
-2 15 4 1 1 0 0 1 1 0 0 0 8
-1 8 3 2 0 0 0 0 0 0 1 0 8
-3 20 1 1 0 1 0 0 0 1 1 10 2
-1 10 1 4 1 0 0 1 0 1 0 10 2
-0 23 1 2 0 1 0 0 0 0 1 0 8
-3 21 2 3 0 0 0 0 0 0 1 100 1
-0 19 2 1 0 0 0 0 0 0 1 1 1
-2 19 4 2 1 0 0 1 0 1 0 10 1
-3 18 1 3 1 0 0 1 1 1 0 0 8
-1 7 4 3 0 1 1 0 0 1 1 0 1
-2 11 4 3 0 1 1 0 0 0 0 1 2
-0 8 2 3 0 1 0 0 0 1 1 10 8
-1 15 2 2 1 0 0 1 0 1 0 10 8
-1 11 3 1 0 0 0 0 0 1 1 2 1
-2 9 4 1 0 0 0 0 0 1 0 1 1
-0 16 2 2 1 0 0 1 1 0 0 100 8
-1 16 3 3 0 0 0 0 0 0 1 10 1
-2 22 1 4 1 0 0 0 0 1 0 2 8
-3 25 4 2 1 0 0 0 1 0 0 1 2
-3 14 2 3 1 0 0 0 1 0 0 10 8
-0 13 3 4 0 1 1 0 0 1 1 0 1
-0 8 4 2 0 1 1 0 0 0 1 100 2
-2 13 4 1 1 0 0 1 1 0 0 1 8
-3 13 2 2 1 0 0 1 0 0 0 10 8
-3 17 4 4 1 0 0 1 1 1 0 0 1
-0 11 2 4 1 0 0 1 1 0 0 0 8
-2 12 1 4 0 1 1 0 0 0 1 2 1
-1 14 4 4 0 0 1 0 0 1 1 1 1
-1 20 3 2 0 0 0 0 0 1 1 2 2
-0 18 3 1 1 0 0 1 0 0 0 2 2
-3 16 2 4 0 0 1 0 0 0 0 1 8
-0 21 3 2 0 1 0 0 0 0 0 2 2
-2 4 1 3 0 1 0 0 0 1 1 1 2
-1 18 4 4 0 1 0 0 0 1 1 10 1
-3 14 2 4 0 1 1 0 0 0 0 100 1
-2 17 1 2 0 0 0 0 0 1 1 1 2
-1 24 4 2 1 0 0 1 1 0 0 10 2
-3 10 3 1 0 1 1 0 0 0 1 2 8
-2 7 3 2 0 1 1 0 0 0 1 1 2
-1 17 2 3 0 0 0 0 0 0 1 2 2
-0 24 2 1 0 1 1 0 0 0 1 0 1
-1 15 4 4 1 0 0 1 0 0 0 1 1
-1 18 1 1 0 0 0 0 0 0 1 1 8
-1 26 2 4 1 0 0 0 1 0 0 10 8
-3 11 1 2 0 1 0 0 0 0 0 10 8
-1 9 1 2 0 1 1 0 0 0 1 100 8
-3 19 4 4 1 0 0 1 0 0 0 100 8
-3 11 2 3 0 0 0 0 0 0 1 100 1
-3 9 2 3 1 0 0 1 1 1 0 2 2
-0 9 3 4 1 0 0 0 1 0 0 10 1
-0 4 2 1 1 0 0 0 1 1 0 0 1
-0 13 3 2 1 0 0 1 1 0 0 100 8
-3 7 1 4 0 1 0 0 0 1 1 100 8
-1 22 4 4 1 0 0 0 1 1 0 0 2
-3 24 2 4 1 0 0 1 0 0 0 100 1
-0 20 3 1 0 1 1 0 0 0 1 0 1
-1 25 3 1 1 0 0 1 0 0 0 2 2
-2 10 3 1 0 1 0 0 0 1 1 0 1
-2 4 2 1 0 0 0 0 0 0 1 100 8
-0 17 4 3 0 0 1 0 0 1 1 100 8
-1 9 2 3 1 0 0 1 0 0 0 0 2
-0 8 4 2 1 0 0 1 1 0 0 1 8
-2 7 2 1 1 0 0 1 0 0 0 2 8
-2 23 4 4 0 1 1 0 0 0 1 100 2
-1 26 3 4 1 0 0 0 0 0 0 1 8
+0 25 4 1 1 0 0 0 0 0 0 1 1
+3 11 3 2 0 1 1 0 0 1 1 100 2
+1 9 1 4 1 0 0 1 1 1 0 2 8
+2 21 2 3 1 0 0 1 1 0 0 10 2
+1 9 2 4 0 1 1 0 0 0 1 1 2
+2 7 1 3 0 0 1 0 0 1 1 1 8
+0 21 4 1 0 1 0 0 0 1 1 100 1
+3 26 3 2 1 0 0 0 1 1 0 10 1
+3 26 3 1 1 0 0 1 1 0 0 1 8
+0 25 4 2 1 0 0 1 1 1 0 0 8
+0 14 1 1 0 1 1 0 0 0 1 10 8
+2 22 4 4 1 0 0 1 0 0 0 10 1
+1 14 4 3 0 1 1 0 0 1 0 2 1
+2 10 2 2 0 1 1 0 0 0 1 2 2
+3 17 2 1 0 1 1 0 0 0 1 0 2
+0 18 1 2 0 1 1 0 0 1 1 1 2
+0 23 2 3 1 0 0 1 1 1 0 10 1
+1 10 3 4 1 0 0 1 1 0 0 100 8
+2 19 3 3 0 1 1 0 0 0 1 0 1
+0 26 4 1 1 0 0 0 0 1 0 2 2
+3 13 1 4 1 0 0 1 0 1 0 2 1
+1 15 2 1 1 0 0 1 0 0 0 10 8
+0 21 3 4 1 0 0 1 1 0 0 2 8
+3 10 4 3 0 0 1 0 0 1 1 1 1
+1 12 1 2 0 0 1 0 0 0 1 10 8
+2 19 1 1 1 0 0 1 1 1 0 100 8
+1 19 4 2 1 0 0 0 1 1 0 10 2
+1 16 1 4 1 0 0 0 1 1 0 0 1
+1 26 2 3 1 0 0 1 0 0 0 100 8
+2 16 4 3 0 1 1 0 0 0 1 1 2
+0 7 2 1 1 0 0 1 1 0 0 10 2
+3 9 4 2 0 1 0 0 0 0 1 10 1
+1 17 3 3 1 0 0 1 1 1 0 10 1
+1 23 1 2 0 1 1 0 0 0 1 1 2
+2 14 3 4 1 0 0 1 1 1 0 100 2
+1 7 4 4 1 0 0 1 1 0 0 2 1
+1 13 4 3 0 1 1 0 0 0 1 1 2
+3 23 4 1 0 0 1 0 0 0 1 0 8
+3 7 3 2 0 1 1 0 0 1 1 0 2
+0 17 1 2 1 0 0 1 1 0 0 100 8
+0 10 1 1 0 1 1 0 0 1 0 10 8
+0 12 2 4 1 0 0 1 1 1 0 1 2
+2 12 4 1 1 0 0 1 1 1 0 0 1
+1 18 4 1 1 0 0 1 1 0 0 2 8
+1 22 1 1 0 1 1 0 0 1 1 2 2
+1 21 1 2 0 0 1 0 0 0 1 0 1
+2 11 4 4 1 0 0 1 1 0 0 10 8
+0 15 3 3 0 1 1 0 0 1 1 1 2
+2 23 3 4 1 0 0 0 0 0 0 2 8
+2 17 4 4 0 1 0 0 0 0 1 2 1
+0 13 2 2 1 0 0 1 1 1 0 0 8
+2 13 3 1 0 1 1 0 0 0 1 100 2
+0 9 3 1 1 0 0 1 0 1 0 0 8
+0 20 1 3 0 1 0 0 0 1 1 2 8
+0 11 1 3 1 0 0 0 1 1 0 1 1
+2 8 1 4 1 0 0 1 0 1 0 2 1
+1 20 2 1 1 0 0 1 1 0 0 100 2
+0 22 2 3 0 0 0 0 0 0 1 100 8
+1 13 4 4 1 0 0 0 0 1 0 10 8
+0 16 3 2 0 1 0 0 0 1 1 2 8
+3 22 3 2 0 0 0 0 0 1 1 0 8
+1 8 2 1 0 1 1 0 0 0 1 10 8
+0 19 2 4 0 1 1 0 0 0 1 1 8
+1 11 2 1 1 0 0 1 0 0 0 0 2
+3 15 1 2 1 0 0 0 1 0 0 100 1
+1 17 4 3 0 1 0 0 0 1 1 1 1
+3 24 2 4 0 1 1 0 0 1 1 1 8
+2 24 3 3 1 0 0 1 1 0 0 2 1
+3 8 3 2 1 0 0 1 1 0 0 100 2
+3 21 3 4 0 0 0 0 0 0 0 1 8
+2 26 1 4 1 0 0 1 1 0 0 0 2
+3 14 2 2 0 1 1 0 0 1 1 0 1
+0 8 4 3 0 0 1 0 0 0 1 1 1
+2 9 1 3 1 0 0 1 0 1 0 100 2
+3 12 3 3 0 1 1 0 0 0 1 100 8
+0 7 1 4 1 0 0 1 1 1 0 100 8
+0 10 4 2 0 0 1 0 0 0 1 0 2
+1 24 4 1 0 0 1 0 0 0 1 0 2
+3 16 2 1 0 0 0 0 0 1 1 10 1
+3 18 2 3 0 1 1 0 0 1 1 0 1
+2 16 3 4 0 1 1 0 0 0 1 100 8
+0 11 1 3 0 0 1 0 0 0 1 2 1
+2 14 2 2 0 1 0 0 0 0 1 1 8
+2 12 4 3 1 0 0 1 1 1 0 2 8
+0 8 1 4 0 0 1 0 0 0 1 0 1
+3 25 2 3 1 0 0 1 0 1 0 2 2
+2 15 4 4 1 0 0 1 1 0 0 2 1
+3 20 3 2 1 0 0 1 1 0 0 0 1
+3 23 4 4 0 1 1 0 0 0 1 100 2
+2 25 3 4 1 0 0 0 0 1 0 100 2
+1 25 1 2 1 0 0 0 1 1 0 10 8
+0 24 1 2 0 0 1 0 0 1 1 10 1
+1 15 4 3 1 0 0 1 1 1 0 0 2
+1 24 3 4 0 1 0 0 0 0 1 100 1
+2 20 4 4 0 1 1 0 0 1 0 1 1
+1 22 4 3 1 0 0 0 1 0 0 1 2
+2 18 3 4 0 0 0 0 0 0 0 100 8
+3 19 2 4 0 0 0 0 0 0 1 2 1
+2 18 1 1 1 0 0 0 1 0 0 10 1
+3 16 2 3 1 0 0 1 1 1 0 10 8
+2 20 4 1 0 1 1 0 0 0 1 10 8
);
std::istringstream tests(allPairsTests);
// skip the initial line with the parameter names.
diff --git a/src/test/pict.in b/src/test/pict.in
index 15e9089..77968bb 100755
--- a/src/test/pict.in
+++ b/src/test/pict.in
@@ -23,7 +23,7 @@
# This is the PICT model specifying all parameters and their values
#
spairQueue: 0,1,2,3
-reducerType: 4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
+reducerType: 7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26
divLookup: 1, 2, 3, 4
monTable: 1, 2, 3, 4
buchberger: 0, 1
--
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