[mathicgb] 362/393: Converted all non-F4 reducers to new MonoMonoid monomials and documented them.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:35 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 2fd2f02fc26dc11a9a9913806678cfa308313bf1
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Fri Sep 6 17:06:36 2013 +0200
Converted all non-F4 reducers to new MonoMonoid monomials and documented them.
---
src/mathicgb/F4Reducer.cpp | 8 +-
src/mathicgb/Poly.hpp | 8 +-
src/mathicgb/PolyHashTable.hpp | 6 +-
src/mathicgb/PolyRing.hpp | 15 +++
src/mathicgb/Reducer.hpp | 31 +++--
src/mathicgb/ReducerDedup.cpp | 129 +++++++++-----------
src/mathicgb/ReducerHash.cpp | 32 ++---
src/mathicgb/ReducerHashPack.cpp | 115 +++++++++---------
src/mathicgb/ReducerHelper.hpp | 1 -
src/mathicgb/ReducerNoDedup.cpp | 139 +++++++++++----------
src/mathicgb/ReducerPack.cpp | 170 +++++++++++++-------------
src/mathicgb/ReducerPackDedup.cpp | 247 +++++++++++++++++++-------------------
src/mathicgb/TypicalReducer.cpp | 13 +-
src/mathicgb/TypicalReducer.hpp | 33 ++++-
14 files changed, 502 insertions(+), 445 deletions(-)
diff --git a/src/mathicgb/F4Reducer.cpp b/src/mathicgb/F4Reducer.cpp
index 2f0f25a..ae219f6 100755
--- a/src/mathicgb/F4Reducer.cpp
+++ b/src/mathicgb/F4Reducer.cpp
@@ -90,8 +90,8 @@ public:
);
virtual std::unique_ptr<Poly> regularReduce(
- const_monomial sig,
- const_monomial multiple,
+ ConstMonoRef sig,
+ ConstMonoRef multiple,
size_t basisElement,
const SigPolyBasis& basis
);
@@ -297,8 +297,8 @@ void F4Reducer::classicReducePolySet(
}
std::unique_ptr<Poly> F4Reducer::regularReduce(
- const_monomial sig,
- const_monomial multiple,
+ ConstMonoRef sig,
+ ConstMonoRef multiple,
size_t basisElement,
const SigPolyBasis& basis
) {
diff --git a/src/mathicgb/Poly.hpp b/src/mathicgb/Poly.hpp
index 45ee1af..01c22c0 100755
--- a/src/mathicgb/Poly.hpp
+++ b/src/mathicgb/Poly.hpp
@@ -83,10 +83,10 @@ public:
return std::pair<coefficient, const_monomial>
(getCoefficient(), getMonomial());
}
- const_term term() const {
- const_term t;
- t.monom = getMonomial();
- t.coeff = getCoefficient();
+ NewConstTerm term() const {
+ NewConstTerm t;
+ t.mono = getMonomial();
+ t.coef = getCoefficient();
return t;
}
};
diff --git a/src/mathicgb/PolyHashTable.hpp b/src/mathicgb/PolyHashTable.hpp
index 88b45d6..0fd124b 100755
--- a/src/mathicgb/PolyHashTable.hpp
+++ b/src/mathicgb/PolyHashTable.hpp
@@ -87,11 +87,11 @@ public:
}
MATHICGB_INLINE
- std::pair<Node*, bool> insertProduct(const_term a, const_term b)
+ std::pair<Node*, bool> insertProduct(NewConstTerm a, NewConstTerm b)
{
Value prod;
- mRing.coefficientMult(a.coeff, b.coeff, prod);
- return insertProduct(a.monom, b.monom, prod);
+ mRing.coefficientMult(a.coef, b.coef, prod);
+ return insertProduct(*a.mono, *b.mono, prod);
}
MATHICGB_INLINE
diff --git a/src/mathicgb/PolyRing.hpp b/src/mathicgb/PolyRing.hpp
index 237833b..c3781f3 100755
--- a/src/mathicgb/PolyRing.hpp
+++ b/src/mathicgb/PolyRing.hpp
@@ -195,6 +195,21 @@ typedef MonoMonoid<exponent>::ConstMonoPtr const_monomial;
typedef MonoMonoid<exponent>::ConstMonoPtr ConstMonomial;
#endif
+struct NewConstTerm {
+ MonoMonoid<exponent>::ConstMonoPtr mono;
+ coefficient coef;
+};
+
+struct NewTerm {
+ MonoMonoid<exponent>::MonoPtr mono;
+ coefficient coef;
+
+ operator NewConstTerm() const {
+ NewConstTerm t = {mono, coef};
+ return t;
+ }
+};
+
struct const_term {
const_term() {}
const_term(const_coefficient c, const_monomial m) : coeff(c), monom(m) {}
diff --git a/src/mathicgb/Reducer.hpp b/src/mathicgb/Reducer.hpp
index 4228d1f..116ab3f 100755
--- a/src/mathicgb/Reducer.hpp
+++ b/src/mathicgb/Reducer.hpp
@@ -4,12 +4,12 @@
#define MATHICGB_REDUCER_GUARD
#include "PolyRing.hpp"
-#include "Poly.hpp"
#include <memtailor.h>
#include <memory>
MATHICGB_NAMESPACE_BEGIN
+class Poly;
class SigPolyBasis;
class PolyBasis;
@@ -18,6 +18,15 @@ class PolyBasis;
/// @todo: consider changing name of findLeadTerm to leadTerm.
class Reducer {
public:
+ typedef PolyRing::Monoid Monoid;
+ typedef Monoid::Mono Mono;
+ typedef Monoid::MonoRef MonoRef;
+ typedef Monoid::ConstMonoRef ConstMonoRef;
+ typedef Monoid::MonoPtr MonoPtr;
+ typedef Monoid::ConstMonoPtr ConstMonoPtr;
+
+ typedef coefficient Coefficient;
+
virtual ~Reducer();
/// Returns the preferred number of reductions to do at a time. A classic
@@ -70,8 +79,8 @@ public:
/// is not regular top reducible -- this indicates a singular
/// reduction.
virtual std::unique_ptr<Poly> regularReduce(
- const_monomial sig,
- const_monomial multiple,
+ ConstMonoRef sig,
+ ConstMonoRef multiple,
size_t basisElement,
const SigPolyBasis& basis
) = 0;
@@ -140,13 +149,15 @@ public:
/// std::unique_ptr<Reducer>. CREATE may pick up a const PolyRing&
/// by the name ring.
#define MATHICGB_REGISTER_REDUCER(NAME, ID, CREATE) \
- Reducer::Registration MATHICGB_UNIQUE(reducerRegistration) ( \
- NAME, \
- Reducer:: ID, \
- [](const PolyRing& ring) -> std::unique_ptr<Reducer> { \
- return CREATE; \
- } \
- )
+ namespace { \
+ Reducer::Registration MATHICGB_UNIQUE(reducerRegistration) ( \
+ NAME, \
+ Reducer:: ID, \
+ [](const PolyRing& ring) -> std::unique_ptr<Reducer> { \
+ return CREATE; \
+ } \
+ ); \
+ }
MATHICGB_NAMESPACE_END
#endif
diff --git a/src/mathicgb/ReducerDedup.cpp b/src/mathicgb/ReducerDedup.cpp
index 7a324c8..f02110d 100644
--- a/src/mathicgb/ReducerDedup.cpp
+++ b/src/mathicgb/ReducerDedup.cpp
@@ -12,6 +12,8 @@ MATHICGB_NAMESPACE_BEGIN
void reducerDedupDependency() {}
+/// As ReducerNoDedup, except that if two like terms are compared, then
+/// they are removed and replaced by their sum.
template<template<typename> class Queue>
class ReducerDedup : public TypicalReducer {
public:
@@ -22,41 +24,37 @@ public:
return mQueue.getName() + "-dedup";
}
- virtual void insertTail(const_term multiplier, const Poly *f);
- virtual void insert(monomial multiplier, const Poly *f);
+ virtual void insertTail(NewConstTerm multiplier, const Poly& f);
+ virtual void insert(ConstMonoRef multiplier, const Poly& f);
- virtual bool leadTerm(const_term &result);
+ virtual bool leadTerm(NewConstTerm& result);
virtual void removeLeadTerm();
virtual size_t getMemoryUse() const;
-protected:
virtual void resetReducer();
public:
// This Configuration is designed to work with
// mathic::TourTree, mathic::Heap, and mathic::Geobucket
-
class Configuration : public ReducerHelper::DedupConfiguration {
public:
- typedef term Entry;
+ typedef NewTerm Entry;
Configuration(const PolyRing& ring): DedupConfiguration(ring) {}
CompareResult compare(const Entry& a, const Entry& b) const {
- return ring().monomialCompare(a.monom, b.monom);
+ return ring().monoid().compare(*a.mono, *b.mono);
}
Entry deduplicate(Entry a, Entry b) const {
// change a.coeff, and free b.monom
- ring().coefficientAddTo(a.coeff, b.coeff);
- ring().freeMonomial(b.monom);
+ ring().coefficientAddTo(a.coef, b.coef);
+ ring().monoid().freeRaw(*b.mono);
return a;
}
};
private:
- class MonomialFree;
-
const PolyRing& mRing;
- term mLeadTerm;
+ NewTerm mLeadTerm;
bool mLeadTermKnown;
Queue<Configuration> mQueue;
};
@@ -64,98 +62,78 @@ private:
template<template<typename> class Q>
ReducerDedup<Q>::ReducerDedup(const PolyRing& ring):
mRing(ring),
- mLeadTerm(0, mRing.allocMonomial()),
mLeadTermKnown(false),
- mQueue(Configuration(ring)) {
+ mQueue(Configuration(ring))
+{
+ mLeadTerm.mono = mRing.monoid().alloc().release();
}
template<template<typename> class Q>
-class ReducerDedup<Q>::MonomialFree {
-public:
- MonomialFree(const PolyRing& ring): mRing(ring) {}
-
- bool proceed(term entry)
- {
- mRing.freeMonomial(entry.monom);
- return true;
- }
-private:
- const PolyRing& mRing;
-};
-
-template<template<typename> class Q>
ReducerDedup<Q>::~ReducerDedup() {
resetReducer();
- mRing.freeMonomial(mLeadTerm.monom);
+ mRing.monoid().freeRaw(*mLeadTerm.mono);
}
-///////////////////////////////////////
-// External interface routines ////////
-///////////////////////////////////////
template<template<typename> class Q>
-void ReducerDedup<Q>::insertTail(const_term multiple, const Poly* poly) {
- if (poly->nTerms() <= 1)
+void ReducerDedup<Q>::insertTail(NewConstTerm multiple, const Poly& poly) {
+ if (poly.nTerms() <= 1)
return;
mLeadTermKnown = false;
- Poly::const_iterator i = poly->begin();
- for (++i; i != poly->end(); ++i) {
- term t;
- t.monom = mRing.allocMonomial();
- mRing.monomialMult(multiple.monom, i.getMonomial(), t.monom);
- mRing.coefficientMult(multiple.coeff, i.getCoefficient(), t.coeff);
+ auto it = poly.begin();
+ const auto end = poly.end();
+ for (++it; it != end; ++it) {
+ NewTerm t;
+ t.mono = mRing.monoid().alloc().release();
+ mRing.monoid().multiply(*multiple.mono, it.getMonomial(), *t.mono);
+ mRing.coefficientMult(multiple.coef, it.getCoefficient(), t.coef);
mQueue.push(t);
}
}
template<template<typename> class Q>
-void ReducerDedup<Q>::insert(monomial multiple, const Poly* poly) {
- if (poly->isZero())
+void ReducerDedup<Q>::insert(ConstMonoRef multiple, const Poly& poly) {
+ if (poly.isZero())
return;
mLeadTermKnown = false;
- for (Poly::const_iterator i = poly->begin(); i != poly->end(); ++i) {
- term t(i.getCoefficient(), mRing.allocMonomial());
- mRing.monomialMult(multiple, i.getMonomial(), t.monom);
+ const auto end = poly.end();
+ for (auto it = poly.begin(); it != end; ++it) {
+ NewTerm t = {mRing.monoid().alloc().release(), it.getCoefficient()};
+ mRing.monoid().multiply(multiple, it.getMonomial(), *t.mono);
mQueue.push(t);
}
}
template<template<typename> class Q>
-bool ReducerDedup<Q>::leadTerm(const_term& result) {
- if (mLeadTermKnown) {
- result = mLeadTerm;
- return true;
- }
-
- do {
- if (mQueue.empty())
- return false;
- mLeadTerm = mQueue.top();
- mQueue.pop();
-
- while (true) {
+bool ReducerDedup<Q>::leadTerm(NewConstTerm& result) {
+ if (!mLeadTermKnown) {
+ do {
if (mQueue.empty())
- break;
-
- term entry = mQueue.top();
- if (!mRing.monomialEQ(entry.monom, mLeadTerm.monom))
- break;
- mRing.coefficientAddTo(mLeadTerm.coeff, entry.coeff);
- mRing.freeMonomial(entry.monom);
+ return false;
+ mLeadTerm = mQueue.top();
mQueue.pop();
- }
- } while (mRing.coefficientIsZero(mLeadTerm.coeff));
+
+ while (!mQueue.empty()) {
+ auto entry = mQueue.top();
+ if (!mRing.monoid().equal(*entry.mono, *mLeadTerm.mono))
+ break;
+ mRing.coefficientAddTo(mLeadTerm.coef, entry.coef);
+ mRing.monoid().freeRaw(*entry.mono);
+ mQueue.pop();
+ }
+ } while (mRing.coefficientIsZero(mLeadTerm.coef));
+ mLeadTermKnown = true;
+ }
result = mLeadTerm;
- mLeadTermKnown = true;
return true;
}
template<template<typename> class Q>
void ReducerDedup<Q>::removeLeadTerm() {
if (!mLeadTermKnown) {
- const_term dummy;
+ NewConstTerm dummy;
leadTerm(dummy);
}
mLeadTermKnown = false;
@@ -163,6 +141,19 @@ void ReducerDedup<Q>::removeLeadTerm() {
template<template<typename> class Q>
void ReducerDedup<Q>::resetReducer() {
+ class MonomialFree {
+ public:
+ MonomialFree(const PolyRing& ring): mRing(ring) {}
+
+ bool proceed(NewTerm entry)
+ {
+ mRing.monoid().freeRaw(*entry.mono);
+ return true;
+ }
+ private:
+ const PolyRing& mRing;
+ };
+
MonomialFree freeer(mRing);
mQueue.forAll(freeer);
mQueue.clear();
diff --git a/src/mathicgb/ReducerHash.cpp b/src/mathicgb/ReducerHash.cpp
index b19561f..e0f4028 100644
--- a/src/mathicgb/ReducerHash.cpp
+++ b/src/mathicgb/ReducerHash.cpp
@@ -13,6 +13,10 @@ MATHICGB_NAMESPACE_BEGIN
void reducerHashDependency() {}
+/// The simplest reducer using a hashtable. All terms are in the hash table
+/// and in the queue. There are no duplicates as new terms are looked up in
+/// the hash table before insertion into the queue. The coefficient is
+/// stored in the hash table.
template<template<typename> class Queue>
class ReducerHash : public TypicalReducer {
public:
@@ -22,15 +26,14 @@ public:
return mQueue.getName() + "-hashed";
}
- void insertTail(const_term multiplier, const Poly *f);
- void insert(monomial multiplier, const Poly *f);
+ void insertTail(NewConstTerm multiplier, const Poly& f);
+ void insert(ConstMonoRef multiplier, const Poly& f);
- virtual bool leadTerm(const_term& result);
+ virtual bool leadTerm(NewConstTerm& result);
void removeLeadTerm();
size_t getMemoryUse() const;
-protected:
void resetReducer();
public:
@@ -60,12 +63,13 @@ ReducerHash<Q>::ReducerHash(const PolyRing &ring):
{}
template<template<typename> class Q>
-void ReducerHash<Q>::insertTail(const_term multiplier, const Poly *g1) {
- if (g1->nTerms() <= 1) return;
+void ReducerHash<Q>::insertTail(NewConstTerm multiplier, const Poly& f) {
+ if (f.nTerms() <= 1)
+ return;
mNodesTmp.clear();
- auto it = g1->begin();
- const auto end = g1->end();
+ auto it = f.begin();
+ const auto end = f.end();
for (++it; it != end; ++it) {
auto p = mHashTable.insertProduct(it.term(), multiplier);
if (p.second)
@@ -76,10 +80,10 @@ void ReducerHash<Q>::insertTail(const_term multiplier, const Poly *g1) {
}
template<template<typename> class Q>
-void ReducerHash<Q>::insert(monomial multiplier, const Poly *g1) {
+void ReducerHash<Q>::insert(ConstMonoRef multiplier, const Poly& f) {
mNodesTmp.clear();
- const auto end = g1->end();
- for (auto it = g1->begin(); it != end; ++it) {
+ const auto end = f.end();
+ for (auto it = f.begin(); it != end; ++it) {
auto p = mHashTable.insertProduct
(it.getMonomial(), multiplier, it.getCoefficient());
if (p.second)
@@ -90,12 +94,12 @@ void ReducerHash<Q>::insert(monomial multiplier, const Poly *g1) {
}
template<template<typename> class Q>
-bool ReducerHash<Q>::leadTerm(const_term& result) {
+bool ReducerHash<Q>::leadTerm(NewConstTerm& result) {
while (!mQueue.empty()) {
const auto top = mQueue.top();
if (!mRing.coefficientIsZero(top->value())) {
- result.coeff = top->value();
- result.monom = Monoid::toOld(top->mono());
+ result.coef = top->value();
+ result.mono = top->mono().ptr();
return true;
}
mQueue.pop();
diff --git a/src/mathicgb/ReducerHashPack.cpp b/src/mathicgb/ReducerHashPack.cpp
index 7864d95..c71d879 100644
--- a/src/mathicgb/ReducerHashPack.cpp
+++ b/src/mathicgb/ReducerHashPack.cpp
@@ -13,6 +13,21 @@ MATHICGB_NAMESPACE_BEGIN
void reducerHashPackDependency() {}
+/// A combination of ReducerHash and ReducerPack. Each entry in the queue
+/// corresponds to a term (times a multiplier) of a polynomial. When such a
+/// term is taken off the queue, we advance it to the next term of the
+/// corresponding polynomial and push that back into the queue. Each entry
+/// in the queue is also associated to a hash table entry, where the
+/// data is stored - the entries in the queue are just pointers into
+/// hash table nodes. There are no like terms to add up in the queue, since
+/// the hash table identifies such before insertion into the queue.
+///
+/// There is no need for the complexity of chaining as in ReducerPackDedup,
+/// since we simply keep advancing through the terms in a polynomial until
+/// there are no more terms or we get a term that is unlike any other term
+/// in the queue. We could have stored a list of like terms for each
+/// entry in the queue as in ReducerPackDedup, which might reduce the size of
+/// the queue, but this is a good compromise that leads to simpler code.
template<template<typename> class Queue>
class ReducerHashPack : public TypicalReducer {
public:
@@ -23,26 +38,25 @@ public:
return mQueue.getName() + "-hashed-packed";
}
- virtual void insertTail(const_term multiplier, const Poly *f);
- virtual void insert(monomial multiplier, const Poly *f);
+ virtual void insertTail(NewConstTerm multiplier, const Poly& f);
+ virtual void insert(ConstMonoRef multiplier, const Poly& f);
- virtual bool leadTerm(const_term &result);
+ virtual bool leadTerm(NewConstTerm& result);
virtual void removeLeadTerm();
virtual size_t getMemoryUse() const;
-protected:
virtual void resetReducer();
private:
// Represents a term multiple of a polynomial,
// together with a current term of the multiple.
struct MultipleWithPos {
- MultipleWithPos(const Poly& poly, const_term multiple);
+ MultipleWithPos(const Poly& poly, NewConstTerm multiple);
Poly::const_iterator pos;
Poly::const_iterator const end;
- const_term const multiple;
+ NewTerm multiple;
PolyHashTable::Node* node;
void destroy(const PolyRing& ring);
@@ -57,8 +71,6 @@ private:
}
};
- class MonomialFree;
-
void insertEntry(MultipleWithPos* entry);
const PolyRing& mRing;
@@ -76,85 +88,63 @@ ReducerHashPack<Q>::ReducerHashPack(const PolyRing& ring):
{}
template<template<typename> class Q>
-class ReducerHashPack<Q>::MonomialFree {
-public:
- MonomialFree(const PolyRing& ring): mRing(ring) {}
-
- bool proceed(MultipleWithPos* entry) {
- entry->destroy(mRing);
- return true;
- }
-private:
- const PolyRing& mRing;
-};
-
-template<template<typename> class Q>
ReducerHashPack<Q>::~ReducerHashPack() {
resetReducer();
}
template<template<typename> class Q>
-void ReducerHashPack<Q>::insertTail(const_term multiple, const Poly* poly) {
- MATHICGB_ASSERT(poly != 0);
- MATHICGB_ASSERT(&poly->ring() == &mRing);
- if (poly->nTerms() < 2)
+void ReducerHashPack<Q>::insertTail(NewConstTerm multiple, const Poly& poly) {
+ MATHICGB_ASSERT(&poly.ring() == &mRing);
+ if (poly.nTerms() <= 1)
return;
- MultipleWithPos* entry =
- new (mPool.alloc()) MultipleWithPos(*poly, multiple);
+ auto entry = new (mPool.alloc()) MultipleWithPos(poly, multiple);
++entry->pos;
insertEntry(entry);
}
template<template<typename> class Q>
-void ReducerHashPack<Q>::insert(monomial multiple, const Poly* poly) {
- MATHICGB_ASSERT(poly != 0);
- MATHICGB_ASSERT(&poly->ring() == &mRing);
- if (poly->isZero())
+void ReducerHashPack<Q>::insert(ConstMonoRef multiple, const Poly& poly) {
+ MATHICGB_ASSERT(&poly.ring() == &mRing);
+ if (poly.isZero())
return;
- term termMultiple(1, multiple);
- insertEntry(new (mPool.alloc()) MultipleWithPos(*poly, termMultiple));
-}
-
-namespace {
- const_term allocTerm(const PolyRing& ring, const_term term) {
- monomial mono = ring.allocMonomial();
- ring.monomialCopy(term.monom, mono);
- return const_term(term.coeff, mono);
- }
+ NewConstTerm termMultiple = {multiple.ptr(), 1};
+ insertEntry(new (mPool.alloc()) MultipleWithPos(poly, termMultiple));
}
template<template<typename> class Q>
ReducerHashPack<Q>::MultipleWithPos::MultipleWithPos(
const Poly& poly,
- const_term multiple
+ NewConstTerm multipleParam
):
pos(poly.begin()),
end(poly.end()),
- multiple(allocTerm(poly.ring(), multiple)),
node(0)
-{}
+{
+ multiple.mono = poly.ring().monoid().alloc().release();
+ poly.ring().monoid().copy(*multipleParam.mono, *multiple.mono);
+ multiple.coef = multipleParam.coef;
+}
template<template<typename> class Q>
void ReducerHashPack<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
- ring.freeMonomial
- (const_cast<ConstMonomial&>(multiple.monom).castAwayConst());
+ ring.monoid().freeRaw(*multiple.mono);
// Call the destructor to destruct the iterators into std::vector.
// In debug mode MSVC puts those in a linked list and the destructor
- // has to be called since it takes an iterator off the list. We had
- // memory corruption problems before doing this.
+ // has to be called since it takes an iterator off the list. There were
+ // memory corruption problems in debug mode on MSVC before doing this.
this->~MultipleWithPos();
}
template<template<typename> class Q>
-bool ReducerHashPack<Q>::leadTerm(const_term& result) {
+bool ReducerHashPack<Q>::leadTerm(NewConstTerm& result) {
while (!mQueue.empty()) {
- MultipleWithPos* entry = mQueue.top();
- MATHICGB_ASSERT(entry != 0);
+ auto entry = mQueue.top();
+ MATHICGB_ASSERT(entry != nullptr);
if (!mRing.coefficientIsZero(entry->node->value())) {
- result.coeff = entry->node->value();
- result.monom = Monoid::toOld(entry->node->mono());
+ result.coef = entry->node->value();
+ result.mono = entry->node->mono().ptr();
return true;
}
removeLeadTerm();
@@ -166,12 +156,12 @@ template<template<typename> class Q>
void ReducerHashPack<Q>::removeLeadTerm() {
MATHICGB_ASSERT(!mQueue.empty());
- MultipleWithPos* entry = mQueue.top();
+ auto entry = mQueue.top();
MATHICGB_ASSERT(entry != 0);
// remove node from hash table first since we are going to be changing
// the monomial after this, and if we do that before the hash value will
- // change.
+ // change. That might prompt an assert inside the hash table.
mHashTable.remove(entry->node);
MATHICGB_ASSERT(entry->pos != entry->end);
@@ -183,7 +173,7 @@ void ReducerHashPack<Q>::removeLeadTerm() {
mPool.free(entry);
break;
}
-
+
const auto p = mHashTable.insertProduct
(entry->multiple, entry->pos.term());
if (p.second) {
@@ -212,6 +202,18 @@ void ReducerHashPack<Q>::insertEntry(MultipleWithPos* entry) {
template<template<typename> class Q>
void ReducerHashPack<Q>::resetReducer() {
+ class MonomialFree {
+ public:
+ MonomialFree(const PolyRing& ring): mRing(ring) {}
+
+ bool proceed(MultipleWithPos* entry) {
+ entry->destroy(mRing);
+ return true;
+ }
+ private:
+ const PolyRing& mRing;
+ };
+
MonomialFree freeer(mRing);
mQueue.forAll(freeer);
mQueue.clear();
@@ -225,6 +227,7 @@ size_t ReducerHashPack<Q>::getMemoryUse() const {
mHashTable.getMemoryUse();
}
+
MATHICGB_REGISTER_REDUCER(
"TourHashPack",
Reducer_TourTree_Hashed_Packed,
diff --git a/src/mathicgb/ReducerHelper.hpp b/src/mathicgb/ReducerHelper.hpp
index caf933c..fc7d4d1 100755
--- a/src/mathicgb/ReducerHelper.hpp
+++ b/src/mathicgb/ReducerHelper.hpp
@@ -85,7 +85,6 @@ namespace ReducerHelper {
ring.monomialCopy(term.monom, mono);
return const_term(term.coeff, mono);
}
-
}
MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/ReducerNoDedup.cpp b/src/mathicgb/ReducerNoDedup.cpp
index 90b47a1..067e438 100644
--- a/src/mathicgb/ReducerNoDedup.cpp
+++ b/src/mathicgb/ReducerNoDedup.cpp
@@ -12,6 +12,11 @@ MATHICGB_NAMESPACE_BEGIN
void reducerNoDedupDependency() {}
+/// The most straight forward of the reducers. Simply keep a priority queue
+/// with all the pending terms. If two like monomials are compared in the
+/// queue, they are not combined - both stay in the queue. The sum of like
+/// terms is only taken at the end, when the leading term and its
+/// coefficient is determined.
template<template<typename> class Queue>
class ReducerNoDedup : public TypicalReducer {
public:
@@ -22,34 +27,30 @@ public:
return mQueue.getName() + "-nodedup";
}
- virtual void insertTail(const_term multiplier, const Poly *f);
- virtual void insert(monomial multiplier, const Poly *f);
+ virtual void insertTail(NewConstTerm multiplier, const Poly& f);
+ virtual void insert(ConstMonoRef multiplier, const Poly& f);
- virtual bool leadTerm(const_term &result);
+ virtual bool leadTerm(NewConstTerm& result);
virtual void removeLeadTerm();
virtual size_t getMemoryUse() const;
-protected:
virtual void resetReducer();
-public:
+private:
// This Configuration is designed to work with
// mathic::TourTree, mathic::Heap, and mathic::Geobucket
class Configuration : public ReducerHelper::PlainConfiguration {
public:
- typedef term Entry;
+ typedef NewTerm Entry;
Configuration(const PolyRing& ring): PlainConfiguration(ring) {}
CompareResult compare(const Entry& a, const Entry& b) const {
- return ring().monomialLT(a.monom, b.monom);
+ return ring().monoid().lessThan(*a.mono, *b.mono);
}
};
-private:
- class MonomialFree;
-
const PolyRing& mRing;
- term mLeadTerm;
+ NewTerm mLeadTerm;
bool mLeadTermKnown;
Queue<Configuration> mQueue;
};
@@ -57,96 +58,81 @@ private:
template<template<typename> class Q>
ReducerNoDedup<Q>::ReducerNoDedup(const PolyRing& ring):
mRing(ring),
- mLeadTerm(0, mRing.allocMonomial()),
mLeadTermKnown(false),
- mQueue(Configuration(ring)) {
+ mQueue(Configuration(ring))
+{
+ mLeadTerm.mono = mRing.monoid().alloc().release();
}
template<template<typename> class Q>
-class ReducerNoDedup<Q>::MonomialFree {
-public:
- MonomialFree(const PolyRing& ring): mRing(ring) {}
-
- bool proceed(term entry)
- {
- mRing.freeMonomial(entry.monom);
- return true;
- }
-private:
- const PolyRing& mRing;
-};
-
-template<template<typename> class Q>
ReducerNoDedup<Q>::~ReducerNoDedup() {
resetReducer();
- mRing.freeMonomial(mLeadTerm.monom);
+ mRing.monoid().freeRaw(*mLeadTerm.mono);
}
template<template<typename> class Q>
-void ReducerNoDedup<Q>::insertTail(const_term multiple, const Poly* poly) {
- if (poly->nTerms() <= 1)
+void ReducerNoDedup<Q>::insertTail(NewConstTerm multiple, const Poly& poly) {
+ if (poly.nTerms() <= 1)
return;
mLeadTermKnown = false;
- Poly::const_iterator i = poly->begin();
- for (++i; i != poly->end(); ++i)
- {
- term t;
- t.monom = mRing.allocMonomial();
- mRing.monomialMult(multiple.monom, i.getMonomial(), t.monom);
- mRing.coefficientMult(multiple.coeff, i.getCoefficient(), t.coeff);
- mQueue.push(t);
- }
+ auto it = poly.begin();
+ const auto end = poly.end();
+ for (++it; it != end; ++it) {
+ NewTerm t;
+ t.mono = mRing.allocMonomial();
+ mRing.monoid().multiply(*multiple.mono, it.getMonomial(), *t.mono);
+ mRing.coefficientMult(multiple.coef, it.getCoefficient(), t.coef);
+ mQueue.push(t);
+ }
}
template<template<typename> class Q>
-void ReducerNoDedup<Q>::insert(monomial multiple, const Poly* poly) {
- if (poly->isZero())
+void ReducerNoDedup<Q>::insert(ConstMonoRef multiple, const Poly& poly) {
+ if (poly.isZero())
return;
mLeadTermKnown = false;
- for (Poly::const_iterator i = poly->begin(); i != poly->end(); ++i) {
- term t(i.getCoefficient(), mRing.allocMonomial());
- mRing.monomialMult(multiple, i.getMonomial(), t.monom);
+ const auto end = poly.end();
+ for (auto it = poly.begin(); it != end; ++it) {
+ NewTerm t = {mRing.monoid().alloc().release(), it.getCoefficient()};
+ mRing.monoid().multiply(multiple, it.getMonomial(), *t.mono);
mQueue.push(t);
}
}
template<template<typename> class Q>
-bool ReducerNoDedup<Q>::leadTerm(const_term& result) {
- if (mLeadTermKnown) {
- result = mLeadTerm;
- return true;
- }
-
- do {
- if (mQueue.empty())
- return false;
- mLeadTerm = mQueue.top();
- mQueue.pop();
-
- while (true) {
+bool ReducerNoDedup<Q>::leadTerm(NewConstTerm& result) {
+ if (!mLeadTermKnown) {
+ do {
if (mQueue.empty())
- break;
-
- term entry = mQueue.top();
- if (!mRing.monomialEQ(entry.monom, mLeadTerm.monom))
- break;
- mRing.coefficientAddTo(mLeadTerm.coeff, entry.coeff);
- mRing.freeMonomial(entry.monom);
+ return false;
+ mLeadTerm = mQueue.top();
mQueue.pop();
- }
- } while (mRing.coefficientIsZero(mLeadTerm.coeff));
+
+ while (true) {
+ if (mQueue.empty())
+ break;
+
+ auto entry = mQueue.top();
+ if (!mRing.monoid().equal(*entry.mono, *mLeadTerm.mono))
+ break;
+ mRing.coefficientAddTo(mLeadTerm.coef, entry.coef);
+ mRing.monoid().freeRaw(*entry.mono);
+ mQueue.pop();
+ }
+ } while (mRing.coefficientIsZero(mLeadTerm.coef));
+ mLeadTermKnown = true;
+ }
result = mLeadTerm;
- mLeadTermKnown = true;
return true;
}
template<template<typename> class Q>
void ReducerNoDedup<Q>::removeLeadTerm() {
if (!mLeadTermKnown) {
- const_term dummy;
+ NewConstTerm dummy;
leadTerm(dummy);
}
mLeadTermKnown = false;
@@ -154,9 +140,22 @@ void ReducerNoDedup<Q>::removeLeadTerm() {
template<template<typename> class Q>
void ReducerNoDedup<Q>::resetReducer() {
+ class MonomialFree {
+ public:
+ MonomialFree(const PolyRing& ring): mRing(ring) {}
+
+ bool proceed(NewTerm entry) {
+ mRing.monoid().freeRaw(*entry.mono);
+ return true;
+ }
+
+ private:
+ const PolyRing& mRing;
+ };
+
MonomialFree freeer(mRing);
- //mQueue.forAll(freeer);
- // mQueue.clear();
+ mQueue.forAll(freeer);
+ mQueue.clear();
}
template<template<typename> class Q>
diff --git a/src/mathicgb/ReducerPack.cpp b/src/mathicgb/ReducerPack.cpp
index 60ca977..12583e5 100644
--- a/src/mathicgb/ReducerPack.cpp
+++ b/src/mathicgb/ReducerPack.cpp
@@ -12,50 +12,56 @@ MATHICGB_NAMESPACE_BEGIN
void reducerPackDependency() {}
+/// Keep a priority queue with entries that represent a term of a polynomial
+/// times a multiplier. When an entry is popped, move on to the next
+/// term of the polynomial, if any, and push that back into the queue. The
+/// idea is that this reduces the number of elements in the queue, leading
+/// to faster queue operations. Memory is also saved compared to expanding
+/// each new polynomial with n terms into n entries in the queue.
template<template<typename> class Queue>
class ReducerPack : public TypicalReducer {
public:
ReducerPack(const PolyRing& ring):
mRing(ring),
- mLeadTerm(0, mRing.allocMonomial()),
mLeadTermKnown(false),
mQueue(Configuration(ring)),
mPool(sizeof(MultipleWithPos))
- {}
+ {
+ mLeadTerm.mono = mRing.monoid().alloc().release();
+ }
virtual ~ReducerPack() {
resetReducer();
- mRing.freeMonomial(mLeadTerm.monom);
+ mRing.monoid().freeRaw(*mLeadTerm.mono);
}
virtual std::string description() const {
return mQueue.getName() + "-packed";
}
- virtual void insertTail(const_term multiplier, const Poly* f);
- virtual void insert(monomial multiplier, const Poly* f);
+ virtual void insertTail(NewConstTerm multiplier, const Poly& f);
+ virtual void insert(ConstMonoRef multiplier, const Poly& f);
- virtual bool leadTerm(const_term& result);
+ virtual bool leadTerm(NewConstTerm& result);
virtual void removeLeadTerm();
virtual size_t getMemoryUse() const;
-protected:
+private:
virtual void resetReducer();
-private:
// Represents a term multiple of a polynomial,
// together with a current term of the multiple.
struct MultipleWithPos {
- MultipleWithPos(const Poly& poly, const_term multiple);
+ MultipleWithPos(const Poly& poly, NewConstTerm multiple);
Poly::const_iterator pos;
Poly::const_iterator const end;
- const_term const multiple;
+ NewTerm multiple;
// invariant: current is the monomial product of multiple.monom
// and pos.getMonomial().
- monomial current;
+ MonoPtr current;
// Ensures the invariant, so sets current to the product of
// multiple.monom and pos.getMonomial().
@@ -69,130 +75,117 @@ 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->current, *b->current);
}
};
private:
- class MonomialFree {
- public:
- MonomialFree(const PolyRing& ring): mRing(ring) {}
-
- bool proceed(MultipleWithPos* entry) {
- entry->destroy(mRing);
- return true;
- }
-
- private:
- const PolyRing& mRing;
- };
-
const PolyRing& mRing;
- term mLeadTerm;
+ NewTerm mLeadTerm;
bool mLeadTermKnown;
Queue<Configuration> mQueue;
memt::BufferPool mPool;
};
template<template<typename> class Q>
-void ReducerPack<Q>::insertTail(const_term multiple, const Poly* poly)
+void ReducerPack<Q>::insertTail(NewConstTerm multiple, const Poly& poly)
{
- if (poly->nTerms() <= 1)
+ if (poly.nTerms() <= 1)
return;
mLeadTermKnown = false;
MultipleWithPos* entry =
- new (mPool.alloc()) MultipleWithPos(*poly, multiple);
+ new (mPool.alloc()) MultipleWithPos(poly, multiple);
++entry->pos;
- entry->computeCurrent(poly->ring());
+ entry->computeCurrent(poly.ring());
mQueue.push(entry);
}
template<template<typename> class Q>
-void ReducerPack<Q>::insert(monomial multiple, const Poly* poly)
+void ReducerPack<Q>::insert(ConstMonoRef multiple, const Poly& poly)
{
- if (poly->isZero())
+ if (poly.isZero())
return;
mLeadTermKnown = false;
- // todo: avoid multiplication by 1
- term termMultiple(1, multiple);
- MultipleWithPos* entry =
- new (mPool.alloc()) MultipleWithPos(*poly, termMultiple);
- entry->computeCurrent(poly->ring());
+ NewConstTerm termMultiple = {multiple.ptr(), 1};
+ auto entry = new (mPool.alloc()) MultipleWithPos(poly, termMultiple);
+ entry->computeCurrent(poly.ring());
mQueue.push(entry);
}
template<template<typename> class Q>
-ReducerPack<Q>::MultipleWithPos::MultipleWithPos
-(const Poly& poly, const_term multipleParam):
+ReducerPack<Q>::MultipleWithPos::MultipleWithPos(
+ const Poly& poly,
+ NewConstTerm multipleParam
+):
pos(poly.begin()),
end(poly.end()),
- multiple(ReducerHelper::allocTermCopy(poly.ring(), multipleParam)),
- current(poly.ring().allocMonomial()) {}
+ current(poly.ring().allocMonomial())
+{
+ multiple.mono = poly.ring().monoid().alloc().release();
+ poly.ring().monoid().copy(*multipleParam.mono, *multiple.mono);
+ multiple.coef = multipleParam.coef;
+}
template<template<typename> class Q>
void ReducerPack<Q>::MultipleWithPos::computeCurrent(const PolyRing& ring) {
- ring.monomialMult(multiple.monom, pos.getMonomial(), current);
+ ring.monoid().multiply(*multiple.mono, pos.getMonomial(), *current);
}
template<template<typename> class Q>
void ReducerPack<Q>::MultipleWithPos::currentCoefficient
(const PolyRing& ring, coefficient& coeff) {
- ring.coefficientMult(multiple.coeff, pos.getCoefficient(), coeff);
+ ring.coefficientMult(multiple.coef, pos.getCoefficient(), coeff);
}
template<template<typename> class Q>
void ReducerPack<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
- ring.freeMonomial(current);
- ConstMonomial& monom = const_cast<ConstMonomial&>(multiple.monom);
- ring.freeMonomial(monom.castAwayConst());
+ ring.monoid().freeRaw(*current);
+ ring.monoid().freeRaw(*multiple.mono);
// Call the destructor to destruct the iterators into std::vector.
// In debug mode MSVC puts those in a linked list and the destructor
- // has to be called since it takes an iterator off the list. We had
- // memory corruption problems before doing this.
+ // has to be called since it takes an iterator off the list. There were
+ // memory corruption problems in debug mode before doing this on MSVC.
this->~MultipleWithPos();
}
template<template<typename> class Q>
-bool ReducerPack<Q>::leadTerm(const_term& result)
+bool ReducerPack<Q>::leadTerm(NewConstTerm& result)
{
- if (mLeadTermKnown) {
- result = mLeadTerm;
- return true;
- }
-
- do {
- if (mQueue.empty())
- return false;
- MultipleWithPos* entry = mQueue.top();
- mLeadTerm.monom.swap(entry->current);
- entry->currentCoefficient(mRing, mLeadTerm.coeff);
+ if (!mLeadTermKnown) {
+ do {
+ if (mQueue.empty())
+ return false;
+ MultipleWithPos* entry = mQueue.top();
+ std::swap(mLeadTerm.mono, entry->current);
+ entry->currentCoefficient(mRing, mLeadTerm.coef);
- while (true) {
- ++entry->pos;
- if (entry->pos == entry->end) {
- mQueue.pop();
- entry->destroy(mRing);
- mPool.free(entry);
- } else {
- entry->computeCurrent(mRing);
- mQueue.decreaseTop(entry);
- }
+ while (true) {
+ ++entry->pos;
+ if (entry->pos == entry->end) {
+ mQueue.pop();
+ entry->destroy(mRing);
+ mPool.free(entry);
+ } else {
+ entry->computeCurrent(mRing);
+ mQueue.decreaseTop(entry);
+ }
- if (mQueue.empty())
- break;
+ if (mQueue.empty())
+ break;
- entry = mQueue.top();
- if (!mRing.monomialEQ(entry->current, mLeadTerm.monom))
- break;
- coefficient coeff;
- entry->currentCoefficient(mRing, coeff);
- mRing.coefficientAddTo
- (mLeadTerm.coeff, const_cast<const coefficient&>(coeff));
- }
- } while (mRing.coefficientIsZero(mLeadTerm.coeff));
+ entry = mQueue.top();
+ if (!mRing.monoid().equal(*entry->current, *mLeadTerm.mono))
+ break;
+ coefficient coef;
+ entry->currentCoefficient(mRing, coef);
+ mRing.coefficientAddTo
+ (mLeadTerm.coef, const_cast<const coefficient&>(coef));
+ }
+ } while (mRing.coefficientIsZero(mLeadTerm.coef));
+ }
result = mLeadTerm;
mLeadTermKnown = true;
@@ -203,7 +196,7 @@ template<template<typename> class Q>
void ReducerPack<Q>::removeLeadTerm()
{
if (!mLeadTermKnown) {
- const_term dummy;
+ NewConstTerm dummy;
leadTerm(dummy);
}
mLeadTermKnown = false;
@@ -212,6 +205,19 @@ void ReducerPack<Q>::removeLeadTerm()
template<template<typename> class Q>
void ReducerPack<Q>::resetReducer()
{
+ class MonomialFree {
+ public:
+ MonomialFree(const PolyRing& ring): mRing(ring) {}
+
+ bool proceed(MultipleWithPos* entry) {
+ entry->destroy(mRing);
+ return true;
+ }
+
+ private:
+ const PolyRing& mRing;
+ };
+
MonomialFree freeer(mRing);
mQueue.forAll(freeer);
mQueue.clear();
diff --git a/src/mathicgb/ReducerPackDedup.cpp b/src/mathicgb/ReducerPackDedup.cpp
index 848168b..5ef4d2e 100644
--- a/src/mathicgb/ReducerPackDedup.cpp
+++ b/src/mathicgb/ReducerPackDedup.cpp
@@ -12,6 +12,18 @@ MATHICGB_NAMESPACE_BEGIN
void reducerPackDedupDependency() {}
+/// As ReducerPack, with an extra feature: if two items with the same current
+/// monomial in the queue are compared by the queue, then combine the first
+/// into the second. That way, the second can be removed from the queue.
+/// This requires keeping a linked list with each entry of the other entries
+/// that have been combined into it, since we need to move on to the next term
+/// of all of those entries. This technique further reduces the number of
+/// entries in the queue.
+///
+/// Note that the linked lists are circular to make it fast to append two
+/// linked lists. The trick is that you can combine two distinct circular
+/// lists by swapping the next pointers of any one node in the first list and
+/// of any one node in the second list.
template<template<typename> class Queue>
class ReducerPackDedup : public TypicalReducer {
public:
@@ -22,37 +34,35 @@ public:
return mQueue.getName() + "-packed";
}
- virtual void insertTail(const_term multiplier, const Poly* f);
- virtual void insert(monomial multiplier, const Poly* f);
+ virtual void insertTail(NewConstTerm multiplier, const Poly& f);
+ virtual void insert(ConstMonoRef multiplier, const Poly& f);
- virtual bool leadTerm(const_term& result);
+ virtual bool leadTerm(NewConstTerm& result);
virtual void removeLeadTerm();
virtual size_t getMemoryUse() const;
-protected:
virtual void resetReducer();
private:
// Represents a term multiple of a polynomial,
// together with a current term of the multiple.
-public:
struct MultipleWithPos {
- MultipleWithPos(const Poly& poly, const_term multiple);
+ MultipleWithPos(const Poly& poly, NewConstTerm multiple);
Poly::const_iterator pos;
Poly::const_iterator const end;
- const_term const multiple;
+ NewTerm multiple;
// invariant: current is the monomial product of multiple.monom
// and pos.getMonomial().
- monomial current;
+ MonoPtr current;
// Ensures the invariant, so sets current to the product of
// multiple.monom and pos.getMonomial().
void computeCurrent(const PolyRing& ring);
- void currentCoefficient(const PolyRing& ring, coefficient& coeff);
- void addCurrentCoefficient(const PolyRing& ring, coefficient& coeff);
+ void currentCoefficient(const PolyRing& ring, Coefficient& coeff);
+ void addCurrentCoefficient(const PolyRing& ring, Coefficient& coeff);
void destroy(const PolyRing& ring);
// Points to a circular list of entries that have the same current
@@ -72,7 +82,7 @@ public:
typedef MultipleWithPos* Entry;
Configuration(const PolyRing& ring): DedupConfiguration(ring) {}
CompareResult compare(const Entry& a, const Entry& b) const {
- return ring().monomialCompare(a->current, b->current);
+ return ring().monoid().compare(*a->current, *b->current);
}
Entry deduplicate(Entry a, Entry b) const {
a->mergeChains(*b);
@@ -83,7 +93,7 @@ private:
class MonomialFree;
const PolyRing& mRing;
- term mLeadTerm;
+ NewTerm mLeadTerm;
bool mLeadTermKnown;
Queue<Configuration> mQueue;
memt::BufferPool mPool;
@@ -92,94 +102,80 @@ private:
template<template<typename> class Q>
ReducerPackDedup<Q>::ReducerPackDedup(const PolyRing& ring):
mRing(ring),
- mLeadTerm(0, mRing.allocMonomial()),
mLeadTermKnown(false),
mQueue(Configuration(ring)),
- mPool(sizeof(MultipleWithPos)) {
-}
-
-template<template<typename> class Q>
-class ReducerPackDedup<Q>::MonomialFree
+ mPool(sizeof(MultipleWithPos))
{
-public:
- MonomialFree(const PolyRing& ring): mRing(ring) {}
-
- bool proceed(MultipleWithPos* entry)
- {
- entry->destroy(mRing);
- return true;
- }
-private:
- const PolyRing& mRing;
-};
+ mLeadTerm.mono = mRing.monoid().alloc().release();
+}
template<template<typename> class Q>
ReducerPackDedup<Q>::~ReducerPackDedup() {
resetReducer();
- mRing.freeMonomial(mLeadTerm.monom);
+ mRing.monoid().freeRaw(*mLeadTerm.mono);
}
template<template<typename> class Q>
-void ReducerPackDedup<Q>::insertTail(const_term multiple, const Poly* poly) {
- if (poly->nTerms() <= 1)
+void ReducerPackDedup<Q>::insertTail(NewConstTerm multiple, const Poly& poly) {
+ if (poly.nTerms() <= 1)
return;
mLeadTermKnown = false;
- MultipleWithPos* entry =
- new (mPool.alloc()) MultipleWithPos(*poly, multiple);
+ auto entry = new (mPool.alloc()) MultipleWithPos(poly, multiple);
++entry->pos;
- entry->computeCurrent(poly->ring());
+ entry->computeCurrent(poly.ring());
mQueue.push(entry);
}
template<template<typename> class Q>
-void ReducerPackDedup<Q>::insert(monomial multiple, const Poly* poly) {
- if (poly->isZero())
+void ReducerPackDedup<Q>::insert(ConstMonoRef multiple, const Poly& poly) {
+ if (poly.isZero())
return;
mLeadTermKnown = false;
- // todo: avoid multiplication by 1
- term termMultiple(1, multiple);
- MultipleWithPos* entry =
- new (mPool.alloc()) MultipleWithPos(*poly, termMultiple);
- entry->computeCurrent(poly->ring());
+ NewConstTerm termMultiple = {multiple.ptr(), 1};
+ auto entry = new (mPool.alloc()) MultipleWithPos(poly, termMultiple);
+ entry->computeCurrent(poly.ring());
mQueue.push(entry);
}
template<template<typename> class Q>
ReducerPackDedup<Q>::MultipleWithPos::MultipleWithPos(
const Poly& poly,
- const_term multipleParam
+ NewConstTerm multipleParam
):
pos(poly.begin()),
end(poly.end()),
- multiple(ReducerHelper::allocTermCopy(poly.ring(), multipleParam)),
- current(poly.ring().allocMonomial()),
+ current(poly.ring().monoid().alloc().release()),
chain(this)
-{}
+{
+ multiple.mono = poly.ring().monoid().alloc().release();
+ poly.ring().monoid().copy(*multipleParam.mono, *multiple.mono);
+ multiple.coef = multipleParam.coef;
+}
template<template<typename> class Q>
-void ReducerPackDedup<Q>::MultipleWithPos::computeCurrent
- (const PolyRing& ring)
-{
- ring.monomialMult(multiple.monom, pos.getMonomial(), current);
+void ReducerPackDedup<Q>::MultipleWithPos::computeCurrent(
+ const PolyRing& ring
+) {
+ ring.monoid().multiply(*multiple.mono, pos.getMonomial(), *current);
}
template<template<typename> class Q>
void ReducerPackDedup<Q>::MultipleWithPos::currentCoefficient(
const PolyRing& ring,
- coefficient& coeff
+ Coefficient& coef
) {
- ring.coefficientMult(multiple.coeff, pos.getCoefficient(), coeff);
+ ring.coefficientMult(multiple.coef, pos.getCoefficient(), coef);
}
template<template<typename> class Q>
void ReducerPackDedup<Q>::MultipleWithPos::addCurrentCoefficient(
const PolyRing& ring,
- coefficient& coeff
+ Coefficient& coeff
) {
- coefficient tmp;
- ring.coefficientMult(multiple.coeff, pos.getCoefficient(), tmp);
+ Coefficient tmp;
+ ring.coefficientMult(multiple.coef, pos.getCoefficient(), tmp);
ring.coefficientAddTo(coeff, tmp);
}
@@ -187,16 +183,15 @@ template<template<typename> class Q>
void ReducerPackDedup<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
MultipleWithPos* entry = this;
do {
- ring.freeMonomial(entry->current);
- ConstMonomial& monom = const_cast<ConstMonomial&>(entry->multiple.monom);
- ring.freeMonomial(monom.castAwayConst());
+ ring.monoid().freeRaw(*entry->current);
+ ring.monoid().freeRaw(*entry->multiple.mono);
MultipleWithPos* next = entry->chain;
MATHICGB_ASSERT(next != 0);
// Call the destructor to destruct the iterators into std::vector.
// In debug mode MSVC puts those in a linked list and the destructor
- // has to be called since it takes an iterator off the list. We had
- // memory corruption problems before doing this.
+ // has to be called since it takes an iterator off the list. There were
+ // memory corruption problems in debug mode on MSVC before doing this.
entry->~MultipleWithPos();
entry = next;
@@ -204,81 +199,78 @@ void ReducerPackDedup<Q>::MultipleWithPos::destroy(const PolyRing& ring) {
}
template<template<typename> class Q>
-bool ReducerPackDedup<Q>::leadTerm(const_term& result) {
- if (mLeadTermKnown) {
- result = mLeadTerm;
- return true;
- }
-
- do {
- if (mQueue.empty())
- return false;
- MultipleWithPos* entry = mQueue.top();
- entry->currentCoefficient(mRing, mLeadTerm.coeff);
- while (true) {
- // store the chained elements
- MultipleWithPos* const chainBegin = entry->chain;
- MultipleWithPos* const chainEnd = entry; // the list is circular
- entry->chain = entry; // detach any chained elements
-
- // handle the entry itself
- mLeadTerm.monom.swap(entry->current);
- ++entry->pos;
- if (entry->pos == entry->end) {
- mQueue.pop();
- entry->destroy(mRing);
- mPool.free(entry);
- } else {
- entry->computeCurrent(mRing);
- // Inserted spans must be in descending order
- MATHICGB_ASSERT(mQueue.getConfiguration().ring().
- monomialLT(entry->current, mLeadTerm.monom));
- mQueue.decreaseTop(entry);
- }
-
- // handle any chained elements
- MultipleWithPos* chain = chainBegin;
- while (chain != chainEnd) {
- MATHICGB_ASSERT(chain != 0);
- MATHICGB_ASSERT(mRing.monomialEQ(chain->current, mLeadTerm.monom));
-
- MultipleWithPos* const next = chain->chain;
- chain->chain = chain; // detach from remaining chained elements
-
- chain->addCurrentCoefficient(mRing, mLeadTerm.coeff);
- ++chain->pos;
- if (chain->pos == chain->end) {
- chain->destroy(mRing);
- mPool.free(chain);
+bool ReducerPackDedup<Q>::leadTerm(NewConstTerm& result) {
+ if (!mLeadTermKnown) {
+ do {
+ if (mQueue.empty())
+ return false;
+ auto entry = mQueue.top();
+ entry->currentCoefficient(mRing, mLeadTerm.coef);
+ while (true) {
+ // store the chained elements
+ const auto chainBegin = entry->chain;
+ const auto chainEnd = entry; // the list is circular
+ entry->chain = entry; // detach any chained elements
+
+ // handle the entry itself
+ std::swap(mLeadTerm.mono, entry->current);
+ ++entry->pos;
+ if (entry->pos == entry->end) {
+ mQueue.pop();
+ entry->destroy(mRing);
+ mPool.free(entry);
} else {
- chain->computeCurrent(mRing);
+ entry->computeCurrent(mRing);
// Inserted spans must be in descending order
MATHICGB_ASSERT(mQueue.getConfiguration().ring().
- monomialLT(chain->current, mLeadTerm.monom));
- mQueue.push(chain);
+ monoid().lessThan(*entry->current, *mLeadTerm.mono));
+ mQueue.decreaseTop(entry);
+ }
+
+ // handle any chained elements
+ auto chain = chainBegin;
+ while (chain != chainEnd) {
+ MATHICGB_ASSERT(chain != 0);
+ MATHICGB_ASSERT(mRing.monoid().equal(*chain->current, *mLeadTerm.mono));
+
+ const auto next = chain->chain;
+ chain->chain = chain; // detach from remaining chained elements
+
+ chain->addCurrentCoefficient(mRing, mLeadTerm.coef);
+ ++chain->pos;
+ if (chain->pos == chain->end) {
+ chain->destroy(mRing);
+ mPool.free(chain);
+ } else {
+ chain->computeCurrent(mRing);
+ // Inserted spans must be in descending order
+ MATHICGB_ASSERT(mQueue.getConfiguration().ring().
+ monoid().lessThan(*chain->current, *mLeadTerm.mono));
+ mQueue.push(chain);
+ }
+ chain = next;
}
- chain = next;
- }
- if (mQueue.empty())
- break;
+ if (mQueue.empty())
+ break;
- entry = mQueue.top();
- if (!mRing.monomialEQ(entry->current, mLeadTerm.monom))
- break;
- entry->addCurrentCoefficient(mRing, mLeadTerm.coeff);
- }
- } while (mRing.coefficientIsZero(mLeadTerm.coeff));
+ entry = mQueue.top();
+ if (!mRing.monoid().equal(*entry->current, *mLeadTerm.mono))
+ break;
+ entry->addCurrentCoefficient(mRing, mLeadTerm.coef);
+ }
+ } while (mRing.coefficientIsZero(mLeadTerm.coef));
+ mLeadTermKnown = true;
+ }
result = mLeadTerm;
- mLeadTermKnown = true;
return true;
}
template<template<typename> class Q>
void ReducerPackDedup<Q>::removeLeadTerm() {
if (!mLeadTermKnown) {
- const_term dummy;
+ NewConstTerm dummy;
leadTerm(dummy);
}
mLeadTermKnown = false;
@@ -286,6 +278,19 @@ void ReducerPackDedup<Q>::removeLeadTerm() {
template<template<typename> class Q>
void ReducerPackDedup<Q>::resetReducer() {
+ class MonomialFree {
+ public:
+ MonomialFree(const PolyRing& ring): mRing(ring) {}
+
+ bool proceed(MultipleWithPos* entry) {
+ entry->destroy(mRing);
+ return true;
+ }
+
+ private:
+ const PolyRing& mRing;
+ };
+
MonomialFree freeer(mRing);
mQueue.forAll(freeer);
mQueue.clear();
diff --git a/src/mathicgb/TypicalReducer.cpp b/src/mathicgb/TypicalReducer.cpp
index c0ca77d..53eb20b 100755
--- a/src/mathicgb/TypicalReducer.cpp
+++ b/src/mathicgb/TypicalReducer.cpp
@@ -24,18 +24,19 @@ size_t TypicalReducer::getMemoryUse() const {
}
std::unique_ptr<Poly> TypicalReducer::regularReduce(
- const_monomial sig,
- const_monomial multiple,
+ ConstMonoRef sig,
+ ConstMonoRef multiple,
size_t basisElement,
const SigPolyBasis& basis)
{
const PolyRing& ring = basis.ring();
+ const auto& monoid = ring.monoid();
monomial tproduct = ring.allocMonomial(mArena);
monomial u = ring.allocMonomial(mArena);
- ring.monomialMult(multiple, basis.getLeadMonomial(basisElement), tproduct);
+ monoid.multiply(multiple, basis.getLeadMonomial(basisElement), tproduct);
- size_t reducer = basis.regularReducer(sig, tproduct);
+ size_t reducer = basis.regularReducer(Monoid::toOld(sig), tproduct);
if (reducer == static_cast<size_t>(-1)) {
mArena.freeAllAllocs();
return nullptr; // singular reduction: no regular top reduction possible
@@ -45,7 +46,7 @@ std::unique_ptr<Poly> TypicalReducer::regularReduce(
coefficient coef;
ring.coefficientSet(coef, 1);
- insertTail(const_term(coef, multiple), &basis.poly(basisElement));
+ insertTail(const_term(coef, Monoid::toOld(multiple)), &basis.poly(basisElement));
MATHICGB_ASSERT(ring.coefficientIsOne(basis.getLeadCoefficient(reducer)));
ring.coefficientFromInt(coef, -1);
@@ -57,7 +58,7 @@ std::unique_ptr<Poly> TypicalReducer::regularReduce(
unsigned long long steps = 2; // number of steps in this reduction
for (const_term v; leadTerm(v);) {
MATHICGB_ASSERT(v.coeff != 0);
- reducer = basis.regularReducer(sig, v.monom);
+ reducer = basis.regularReducer(Monoid::toOld(sig), v.monom);
if (reducer == static_cast<size_t>(-1)) { // no reducer found
result->appendTerm(v.coeff, v.monom);
removeLeadTerm();
diff --git a/src/mathicgb/TypicalReducer.hpp b/src/mathicgb/TypicalReducer.hpp
index 19a1228..5e6c1fb 100755
--- a/src/mathicgb/TypicalReducer.hpp
+++ b/src/mathicgb/TypicalReducer.hpp
@@ -26,8 +26,8 @@ public:
virtual unsigned int preferredSetSize() const;
virtual std::unique_ptr<Poly> regularReduce(
- const_monomial sig,
- const_monomial multiple,
+ ConstMonoRef sig,
+ ConstMonoRef multiple,
size_t basisElement,
const SigPolyBasis& basis
);
@@ -58,9 +58,32 @@ public:
protected:
// These are the methods that sub-classes define in order to carry
// out sub-steps in the reduction.
- virtual void insertTail(const_term multiplier, const Poly *f) = 0;
- virtual void insert(monomial multiplier, const Poly *f) = 0;
- virtual bool leadTerm(const_term& result) = 0;
+ virtual void insertTail(const_term multiplier, const Poly* f) {
+ MATHICGB_ASSERT(f != 0);
+ NewConstTerm t = {multiplier.monom, multiplier.coeff};
+ insertTail(t, *f);
+ }
+
+ virtual void insert(monomial multiplier, const Poly* f) {
+ MATHICGB_ASSERT(f != 0);
+ ConstMonoRef mono = multiplier;
+ insert(mono, *f);
+ }
+
+ virtual bool leadTerm(const_term& result) {
+ NewConstTerm t;
+ auto hasLead = leadTerm(t);
+ if (hasLead) {
+ result.monom = Monoid::toOld(*t.mono);
+ result.coeff = t.coef;
+ }
+ return hasLead;
+ }
+
+ virtual void insertTail(NewConstTerm multiplier, const Poly& f) {}
+ virtual void insert(ConstMonoRef multiplier, const Poly& f) {}
+ virtual bool leadTerm(NewConstTerm& lead) {return false;}
+
virtual void removeLeadTerm() = 0;
virtual void resetReducer() = 0;
--
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