[mathicgb] 318/393: Removed FreeModuleOrder from PolyBasis and GroebnerBasis as well as all the code that uses the order from those. Also removed most of the code from FreeModuleOrder.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:28 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 4a48b0a6c7fdbdf7df52a9f4753cf7270e46f93e
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Sat May 11 16:18:14 2013 +0200
Removed FreeModuleOrder from PolyBasis and GroebnerBasis as well as all the code that uses the order from those. Also removed most of the code from FreeModuleOrder.
---
Makefile.am | 3 +-
src/cli/SigGBAction.cpp | 7 +-
src/mathicgb/Basis.cpp | 2 +-
src/mathicgb/Basis.hpp | 3 +-
src/mathicgb/BuchbergerAlg.cpp | 3 +-
src/mathicgb/DivLookup.hpp | 15 +-
src/mathicgb/FreeModuleOrder.cpp | 321 +--------------------------------------
src/mathicgb/FreeModuleOrder.hpp | 11 --
src/mathicgb/GroebnerBasis.cpp | 34 ++---
src/mathicgb/GroebnerBasis.hpp | 32 ++--
src/mathicgb/PairTriangle.cpp | 7 +-
src/mathicgb/PolyBasis.cpp | 4 +-
src/mathicgb/PolyBasis.hpp | 13 +-
src/mathicgb/SigSPairQueue.cpp | 182 +++++++++++++++++++++-
src/mathicgb/SigSPairQueue.hpp | 8 +-
src/mathicgb/SigSPairs.cpp | 4 +-
src/mathicgb/SignatureGB.cpp | 2 +-
src/mathicgb/TypicalReducer.cpp | 6 +-
src/test/F4MatrixBuilder.cpp | 5 +-
19 files changed, 256 insertions(+), 406 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 2e4e4e1..11b2192 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -106,8 +106,7 @@ check_PROGRAMS=$(TESTS)
unittest_LDADD = $(DEPS_LIBS) $(top_builddir)/libmathicgb.la
test_LIBS=
-unittest_SOURCES=src/test/FreeModuleOrderTest.cpp \
- src/test/gtestInclude.cpp src/test/testMain.cpp \
+unittest_SOURCES= src/test/gtestInclude.cpp src/test/testMain.cpp \
src/test/gb-test.cpp src/test/ideals.cpp src/test/poly-test.cpp \
src/test/ideals.hpp src/test/SparseMatrix.cpp \
src/test/QuadMatrixBuilder.cpp src/test/F4MatrixBuilder.cpp \
diff --git a/src/cli/SigGBAction.cpp b/src/cli/SigGBAction.cpp
index f1d95a2..14eaee6 100755
--- a/src/cli/SigGBAction.cpp
+++ b/src/cli/SigGBAction.cpp
@@ -10,12 +10,11 @@
#include <iostream>
SigGBAction::SigGBAction():
- mUseSingularCriterionEarly("earlySingularCriterion",
+ mUseSingularCriterionEarly(
+ "earlySingularCriterion",
"Apply the singular S-pair elimination criterion before queueing "
"that S-pair. Otherwise, the criterion is only checked just before "
- "the S-pair would otherwise cause a polynomial reduction to occur. "
- "This criterion is only relevant to the signature Buchberger "
- "algorithm.",
+ "the S-pair would otherwise cause a polynomial reduction to occur. ",
false),
mPostponeKoszul("postponeKoszul",
diff --git a/src/mathicgb/Basis.cpp b/src/mathicgb/Basis.cpp
index 006b76d..9e3c201 100755
--- a/src/mathicgb/Basis.cpp
+++ b/src/mathicgb/Basis.cpp
@@ -15,7 +15,7 @@ void Basis::insert(std::unique_ptr<Poly>&& p) {
mGenerators.push_back(std::move(p));
}
-void Basis::sort(FreeModuleOrder& order) {
+void Basis::sort() {
const auto& monoid = ring().monoid();
const auto cmp = [&monoid](
const std::unique_ptr<Poly>& a,
diff --git a/src/mathicgb/Basis.hpp b/src/mathicgb/Basis.hpp
index c8981b3..3afbf11 100755
--- a/src/mathicgb/Basis.hpp
+++ b/src/mathicgb/Basis.hpp
@@ -9,7 +9,6 @@
#include <vector>
class Poly;
-class FreeModuleOrder;
// Really: a list of polynomials
// BUT ALSO maybe: includes memory areas for the polynomials?
@@ -37,7 +36,7 @@ public:
bool empty() const {return mGenerators.empty();}
void reserve(size_t size) {mGenerators.reserve(size);}
- void sort(FreeModuleOrder& order);
+ void sort();
private:
Basis(const Basis&); // not available
diff --git a/src/mathicgb/BuchbergerAlg.cpp b/src/mathicgb/BuchbergerAlg.cpp
index 0c6b69d..d5aa751 100755
--- a/src/mathicgb/BuchbergerAlg.cpp
+++ b/src/mathicgb/BuchbergerAlg.cpp
@@ -26,7 +26,7 @@ BuchbergerAlg::BuchbergerAlg(
mRing(*basis.getPolyRing()),
mOrder(FreeModuleOrder::makeOrder(0, *basis.getPolyRing())), // todo: remove
mReducer(reducer),
- mBasis(mRing, *mOrder, DivisorLookup::makeFactory(
+ mBasis(mRing, DivisorLookup::makeFactory(
*basis.getPolyRing(),
divisorLookupType)->create(preferSparseReducers, true)
),
@@ -326,7 +326,6 @@ size_t BuchbergerAlg::getMemoryUse() const {
}
void BuchbergerAlg::printStats(std::ostream& out) const {
- out << " term order: " << mBasis.order().description() << '\n';
out << " reduction type: " << mReducer.description() << '\n';
out << " divisor tab type: " << mBasis.divisorLookup().getName() << '\n';
out << " S-pair queue type: " << mSPairs.name() << '\n';
diff --git a/src/mathicgb/DivLookup.hpp b/src/mathicgb/DivLookup.hpp
old mode 100644
new mode 100755
index 2e6d619..8764d38
--- a/src/mathicgb/DivLookup.hpp
+++ b/src/mathicgb/DivLookup.hpp
@@ -456,7 +456,7 @@ private:
// ensures deterministic behavior.
const const_monomial minSig = mSigBasis.getSignature(mMinLeadGen);
const const_monomial genSig = mSigBasis.getSignature(entry.index);
- int sigCmp = mSigBasis.order().signatureCompare(minSig, genSig);
+ int sigCmp = mSigBasis.monoid().compare(minSig, genSig);
MATHICGB_ASSERT(sigCmp != EQ); // no two generators have same signature
if (sigCmp == GT)
return true;
@@ -621,17 +621,6 @@ public:
_finder.insert(Entry(mon, val));
}
-#if 0
- virtual bool findDivisor(const_monomial sig, const_monomial mon, size_t &val, monomial &result_multiplier)
- {
- DO out(getConfiguration().order(), getConfiguration().getPolyRing(), sig, mon, val, result_multiplier);
- _finder.findAllDivisors(mon, out);
- return out.found();
- }
-#endif
- // ifdef the above code to 0 and this to 1, if you wish to use: choose divisor to be a one wih minimal number
- // of monomial that satisfies sig and divisibility criteria.
-#if 1
virtual size_t regularReducer(const_monomial sig, const_monomial mon) const
{
DOCheckAll out(
@@ -643,7 +632,7 @@ public:
_finder.findAllDivisors(mon, out);
return out.reducer();
}
-#endif
+
unsigned long long getExpQueryCount() const {
return _finder.getConfiguration().getExpQueryCount();
}
diff --git a/src/mathicgb/FreeModuleOrder.cpp b/src/mathicgb/FreeModuleOrder.cpp
index 9999f36..06eef39 100755
--- a/src/mathicgb/FreeModuleOrder.cpp
+++ b/src/mathicgb/FreeModuleOrder.cpp
@@ -13,215 +13,12 @@
#include <limits>
#include <stdexcept>
-// In this file we define various term orders. Some classes need to be
-// specialized to each term order which we do using templates. Those
-// classes are defined here since they should not be used from
-// anywhere else - instead they should be accessed through their
-// virtual interface.
-
-// *******************************************************
-// ** Utility objects
-
-namespace {
- template<class Cmp>
- class Comparer {
- public:
- Comparer(const Cmp& cmp): mCmp(cmp), mComparisons(0) {}
- bool operator()(const PreSPair& a, const PreSPair& b) const {
- ++mComparisons;
- return mCmp.signatureCompare(a.signature, b.signature) == LT;
- }
- size_t comparisons() const {return mComparisons;}
- private:
- const Cmp& mCmp;
- mutable size_t mComparisons;
- };
-
- // Iterator that accesses the field i based on a passed-in iterator.
- template<class PairIterator>
- class IndexIterator {
- public:
-
- typedef typename PairIterator::iterator_category iterator_category;
- typedef decltype(reinterpret_cast<typename PairIterator::value_type*>(0)->i) value_type;
- typedef typename PairIterator::difference_type difference_type;
- typedef value_type* pointer;
- typedef value_type& reference;
-
- IndexIterator(PairIterator pairIterator): mIterator(pairIterator) {}
- IndexIterator& operator++() {++mIterator; return *this;}
- const value_type operator*() const {return mIterator->i;}
- difference_type operator-(const IndexIterator<PairIterator>& it) const {
- return mIterator - it.mIterator;
- }
- bool operator==(const IndexIterator<PairIterator>& it) const {
- return mIterator == it.mIterator;
- }
- bool operator!=(const IndexIterator<PairIterator>& it) const {
- return mIterator != it.mIterator;
- }
-
- private:
- PairIterator mIterator;
- };
-}
-
-// *******************************************************
-// ** SigSPairQueue
-namespace {
- // Configuration of mathic::PairTriangle for use with signature queues.
- template<class Cmp>
- class SigPTConfiguration {
- public:
- SigPTConfiguration
- (GroebnerBasis const& basis, Cmp const& cmp): mBasis(basis), mCmp(cmp) {}
-
- typedef monomial PairData;
- void computePairData(size_t col, size_t row, monomial sig) {
- MATHICGB_ASSERT(mBasis.ratioCompare(col, row) != EQ);
- // ensure that ratio(col) > ratio(row)
- if (mBasis.ratioCompare(col, row) == LT)
- std::swap(col, row);
- mBasis.ring().monomialFindSignature
- (mBasis.getLeadMonomial(col),
- mBasis.getLeadMonomial(row),
- mBasis.getSignature(col), sig);
- }
-
- typedef bool CompareResult;
- bool compare(int colA, int rowA, const_monomial a,
- int colB, int rowB, const_monomial b) const {
- return mCmp.signatureCompare(b, a) == LT;
- }
- bool cmpLessThan(bool v) const {return v;}
-
- GroebnerBasis const& basis() const {return mBasis;}
- Cmp const& comparer() const {return mCmp;}
-
- private:
- GroebnerBasis const& mBasis;
- Cmp const& mCmp;
- };
-
- // Object that stores S-pairs and orders them according to a monomial
- // or signature.
- template<class Cmp>
- class ConcreteSigSPairQueue : public SigSPairQueue {
- public:
- ConcreteSigSPairQueue(GroebnerBasis const& basis, Cmp const& cmp):
- mPairQueue(PC(basis, cmp)) {}
-
- virtual monomial popSignature(Pairs& pairs) {
- pairs.clear();
- if (mPairQueue.empty())
- return 0;
- monomial sig = ring().allocMonomial();
- ring().monomialCopy(mPairQueue.topPairData(), sig);
- do {
- pairs.push_back(mPairQueue.topPair());
- mPairQueue.pop();
- } while
- (!mPairQueue.empty() && ring().monomialEQ(mPairQueue.topPairData(), sig));
- return sig;
- }
-
- virtual void pushPairs(size_t pairWith, IndexSigs& pairs) {
-#ifdef DEBUG
- monomial tmp = ring().allocMonomial();
- for (size_t i = 0; i < pairs.size(); ++i) {
- MATHICGB_ASSERT(pairs[i].i < columnCount());
- mPairQueue.configuration().computePairData
- (columnCount(), pairs[i].i, tmp);
- MATHICGB_ASSERT(ring().monomialEQ(tmp, pairs[i].signature));
- }
- ring().freeMonomial(tmp);
-#endif
-
- if (columnCount() >= std::numeric_limits<BigIndex>::max())
- throw std::overflow_error
- ("Too large basis element index in constructing S-pairs.");
-
- // sort and insert new column
- Comparer<Cmp> cmp(comparer());
- std::sort(pairs.begin(), pairs.end(), cmp);
- //mPreComparisons += cmp.comparisons();
- //order().destructiveSort(pairs);
- typedef IndexIterator<std::vector<PreSPair>::const_iterator> Iter;
- mPairQueue.addColumnDescending(Iter(pairs.begin()), Iter(pairs.end()));
-
- // free signatures
- std::vector<PreSPair>::iterator end = pairs.end();
- for (std::vector<PreSPair>::iterator it = pairs.begin(); it != end; ++it)
- ring().freeMonomial(it->signature);
- pairs.clear();
- }
-
- virtual std::string name() const {return "todo";}
-
- virtual size_t memoryUse() const {return mPairQueue.getMemoryUse();}
-
- virtual size_t pairCount() const {return mPairQueue.pairCount();}
-
- virtual size_t columnCount() const {return mPairQueue.columnCount();}
-
- private:
- ConcreteSigSPairQueue(const ConcreteSigSPairQueue<Cmp>&); // not available
- void operator=(const ConcreteSigSPairQueue<Cmp>&); // not available
-
- // the compiler should be able to resolve these accessors into a direct
- // offset as though these were member variables.
- const GroebnerBasis& basis() const {
- return mPairQueue.configuration().basis();
- }
- const Cmp& comparer() const {return mPairQueue.configuration().comparer();}
- PolyRing const& ring() const {return basis().ring();}
- FreeModuleOrder const& order() const {return basis().order();}
-
- typedef SigPTConfiguration<Cmp> PC;
- mathic::PairQueue<PC> mPairQueue;
- friend struct mathic::PairQueueNamespace::ConstructPairDataFunction<PC>;
- friend struct mathic::PairQueueNamespace::DestructPairDataFunction<PC>;
- };
-}
-
-namespace mathic {
- namespace PairQueueNamespace {
- template<class Cmp>
- struct ConstructPairDataFunction<SigPTConfiguration<Cmp> > {
- inline static void function
- (void* memory, Index col, Index row, SigPTConfiguration<Cmp>& conf) {
- MATHICGB_ASSERT(memory != 0);
- MATHICGB_ASSERT(col > row);
- monomial* pd = new (memory) monomial
- (conf.basis().ring().allocMonomial());
- conf.computePairData(col, row, *pd);
- }
- };
-
- template<class Cmp>
- struct DestructPairDataFunction<SigPTConfiguration<Cmp> > {
- inline static void function
- (monomial* pd, Index col, Index row, SigPTConfiguration<Cmp>& conf) {
- MATHICGB_ASSERT(pd != 0);
- MATHICGB_ASSERT(col > row);
- conf.basis().ring().freeMonomial(*pd);
- }
- };
- }
-}
-
-// *******************************************************
-// ** Term orders
-
-template<class Cmp>
class ConcreteOrder : public FreeModuleOrder {
public:
- ConcreteOrder(const PolyRing& ring): mCmp(ring), mComparisons(0), mPreComparisons(0) {}
- virtual ~ConcreteOrder() {}
+ ConcreteOrder(const PolyRing& ring): mRing(ring) {}
virtual int signatureCompare(const_monomial sigA, const_monomial sigB) const {
- ++mComparisons;
- return mCmp.signatureCompare(sigA, sigB);
+ return mRing.monomialCompare(sigA, sigB);
}
virtual int signatureCompare(
@@ -229,124 +26,18 @@ public:
const_monomial monoB,
const_monomial sigB
) const {
- ++mComparisons;
- return mCmp.signatureCompare(sigA, monoB, sigB);
- }
-
- virtual void sortSignatures(std::vector<PreSPair>& pairs) const {
- Comparer<Cmp> cmp(mCmp);
- std::sort(pairs.begin(), pairs.end(), cmp);
- mPreComparisons += cmp.comparisons();
+ return mRing.monomialCompare(sigA, monoB, sigB);
}
virtual std::string description() const {
- return mCmp.description();
- }
-
- virtual void getStats(size_t& comparisons, size_t& preComparisons) const {
- comparisons = mComparisons;
- preComparisons = mPreComparisons;
- }
-
- virtual std::unique_ptr<SigSPairQueue>
- createSigSPairQueue(GroebnerBasis const& basis) const {
- return std::unique_ptr<SigSPairQueue>
- (new ConcreteSigSPairQueue<Cmp>(basis, mCmp));
+ return "todo";
}
private:
- Cmp mCmp;
- mutable size_t mComparisons;
- mutable size_t mPreComparisons;
+ const PolyRing& mRing;
};
-
-
-// ** Graded reverse lex.
-// Degrees and exponents considered from high index to low index.
-//
-// rule: a[i] < b[i] then a > b
-//
-// also applies to component, which is considered last.
-class OrderA {
-public:
- OrderA(const PolyRing& ring): mRing(&ring) {}
-
- int signatureCompare(const_monomial sigA, const_monomial sigB) const {
- return mRing->monomialCompare(sigA, sigB);
- }
-
- int signatureCompare(const_monomial sigA,
- const_monomial monoB, const_monomial sigB) const {
- return mRing->monomialCompare(sigA, monoB, sigB);
- }
-
- char const* description() const {return "GrevLex IndexDown";}
-
-private:
- PolyRing const* const mRing;
-};
-
-class OrderC
-{
-public:
- OrderC(const PolyRing& ring):
- mRing(&ring), topindex(ring.maxMonomialSize() - 2)
- {}
-
- int signatureCompare(const_monomial sig, const_monomial sig2) const {
- const auto d = sig[topindex] - sig2[topindex];
- if (d < 0) return GT;
- if (d > 0) return LT;
-
- const auto cmp = *sig - *sig2;
- if (cmp < 0) return GT;
- if (cmp > 0) return LT;
-
- return mRing->monomialCompare(sig, sig2);
- }
-
- int signatureCompare(
- const_monomial sig,
- const_monomial m2,
- const_monomial sig2
- ) const {
- const auto d = sig[topindex] - (m2[topindex] + sig2[topindex]);
- if (d < 0) return GT;
- if (d > 0) return LT;
-
- const auto cmp = *sig - *sig2;
- if (cmp < 0) return GT;
- if (cmp > 0) return LT;
-
- return mRing->monomialCompare(sig, m2, sig2);
- }
-
- char const* description() const {return "DegreeUp IndexDown GrevLex";}
-
-private:
- PolyRing const* const mRing;
- const size_t topindex;
-};
-
-void FreeModuleOrder::displayOrderTypes(std::ostream &o)
-{
- o << "FreeModule orders:" << std::endl;
- o << " 1 GrevLex IndexDown" << std::endl;
- o << " 2 DegreeUp IndexUp GrevLex" << std::endl; // done
- o << " 3 DegreeUp IndexDown GrevLex" << std::endl;
- o << " 4 SchreyerGrevLexUp" << std::endl; // done
- o << " 5 SchreyerGrevLexDown" << std::endl; // done
- o << " 6 IndexUp SchreyerGrevLex" << std::endl; // done
- o << " 7 IndexDown SchreyerGrevLex" << std::endl; // done
-}
-
std::unique_ptr<FreeModuleOrder> FreeModuleOrder::makeOrder(FreeModuleOrderType type, const PolyRing& ring)
{
- return make_unique<ConcreteOrder<OrderA>>(ring);
+ return make_unique<ConcreteOrder>(ring);
}
-
-// Local Variables:
-// compile-command: "make -C .. "
-// indent-tabs-mode: nil
-// End:
diff --git a/src/mathicgb/FreeModuleOrder.hpp b/src/mathicgb/FreeModuleOrder.hpp
index 115e49f..1fd3a1a 100755
--- a/src/mathicgb/FreeModuleOrder.hpp
+++ b/src/mathicgb/FreeModuleOrder.hpp
@@ -27,21 +27,10 @@ public:
const_monomial sig2
) const = 0;
- // Sorts in ascending order of signature.
- virtual void sortSignatures(std::vector<PreSPair>& pairs) const = 0;
-
- virtual void getStats(size_t& comparisons, size_t& preComparisons) const = 0;
-
virtual std::string description() const = 0;
- virtual std::unique_ptr<SigSPairQueue>
- createSigSPairQueue(GroebnerBasis const& basis) const = 0;
-
/// @todo: We need at least an enum to make this clearer
static std::unique_ptr<FreeModuleOrder> makeOrder(FreeModuleOrderType type, const PolyRing& ring);
-
- static void displayOrderTypes(std::ostream &o);
-
};
#endif
diff --git a/src/mathicgb/GroebnerBasis.cpp b/src/mathicgb/GroebnerBasis.cpp
index a22d1f0..377c9ef 100755
--- a/src/mathicgb/GroebnerBasis.cpp
+++ b/src/mathicgb/GroebnerBasis.cpp
@@ -1,6 +1,5 @@
// Copyright 2011 Michael E. Stillman
-#define MATHICGB_SLOW_DEBUG
#include "stdinc.h"
#include <iostream>
#include <iomanip>
@@ -10,15 +9,14 @@
GroebnerBasis::GroebnerBasis(
const PolyRing* R0,
- FreeModuleOrder* order,
int divisorLookupType,
int monTableType,
bool preferSparseReducers):
mDivisorLookupFactory
(DivisorLookup::makeFactory(*R0, divisorLookupType)),
- mRatioSorted(RatioOrder(sigLeadRatio, *order)),
+ mRatioSorted(RatioOrder(sigLeadRatio, R0->monoid())),
mMinimalDivisorLookup(mDivisorLookupFactory->create(preferSparseReducers, true)),
- mBasis(*R0, *order, mDivisorLookupFactory->create(preferSparseReducers, true)),
+ mBasis(*R0, mDivisorLookupFactory->create(preferSparseReducers, true)),
mPreferSparseReducers(preferSparseReducers)
{
mTmp = mBasis.ring().allocMonomial();
@@ -147,7 +145,7 @@ again:
mRatioRanks.push_back(rank);
MATHICGB_ASSERT(mRatioRanks.size() == index + 1);
-#ifdef DEBUG
+#ifdef MATHICGB_DEBUG
// Check that at least one space has been left between every rank
MATHICGB_ASSERT(mRatioRanks[*mRatioSorted.begin()] > 0);
MATHICGB_ASSERT(mRatioRanks[*mRatioSorted.rbegin()] <
@@ -178,7 +176,7 @@ size_t GroebnerBasis::regularReducer(
(ring().monomialIsDivisibleBy(term, getLeadMonomial(reducer)));
ring().monomialDivide(term, getLeadMonomial(reducer), m);
ring().monomialMultTo(m, getSignature(reducer));
- MATHICGB_SLOW_ASSERT(order().signatureCompare(sig, m) == GT);
+ MATHICGB_SLOW_ASSERT(monoid().lessThan(m, sig));
ring().freeMonomial(m);
}
#endif
@@ -196,7 +194,7 @@ size_t GroebnerBasis::regularReducerSlow(
continue;
ring().monomialDivide(term, getLeadMonomial(be), m);
ring().monomialMultTo(m, getSignature(be));
- if (order().signatureCompare(sig, m) == GT) {
+ if (monoid().lessThan(m, sig)) {
ring().freeMonomial(m);
return be;
}
@@ -215,7 +213,7 @@ void GroebnerBasis::lowBaseDivisors(
const size_t component = ring().monomialGetComponent(sigNew);
mSignatureLookup[component]->
lowBaseDivisors(divisors, maxDivisors, newGenerator);
-#ifdef DEBUG
+#ifdef MATHICGB_DEBUG
std::vector<size_t> debugValue;
lowBaseDivisorsSlow(debugValue, maxDivisors, newGenerator);
MATHICGB_ASSERT(divisors.size() <= maxDivisors);
@@ -265,7 +263,7 @@ void GroebnerBasis::lowBaseDivisorsSlow(
size_t GroebnerBasis::highBaseDivisor(size_t newGenerator) const {
MATHICGB_ASSERT(newGenerator < size());
size_t highDivisor = divisorLookup().highBaseDivisor(newGenerator);
-#ifdef DEBUG
+#ifdef MATHICGB_DEBUG
size_t debugValue = highBaseDivisorSlow(newGenerator);
MATHICGB_ASSERT((highDivisor == static_cast<size_t>(-1)) ==
(debugValue == static_cast<size_t>(-1)));
@@ -317,10 +315,10 @@ size_t GroebnerBasis::minimalLeadInSigSlow(const_monomial sig) const {
ring().monomialDivide(sig, getSignature(gen), multiplier);
if (minLeadGen != static_cast<size_t>(-1)) {
const_monomial genLead = getLeadMonomial(gen);
- int leadCmp = order().signatureCompare(minLead, multiplier, genLead);
- if (leadCmp == LT)
+ const auto leadCmp = monoid().compare(minLead, multiplier, genLead);
+ if (leadCmp == Monoid::LessThan)
continue;
- if (leadCmp == EQ) {
+ if (leadCmp == Monoid::EqualTo) {
// If same lead monomial in signature, pick the one with fewer terms
// as that one might be less effort to reduce.
const size_t minTerms = poly(minLeadGen).nTerms();
@@ -334,8 +332,10 @@ size_t GroebnerBasis::minimalLeadInSigSlow(const_monomial sig) const {
// is less.
const const_monomial minSig = getSignature(minLeadGen);
const const_monomial genSig = getSignature(gen);
- int sigCmp = order().signatureCompare(minSig, genSig);
- MATHICGB_ASSERT(sigCmp != EQ); // no two generators have same signature
+ int sigCmp = monoid().compare(minSig, genSig);
+
+ // no two generators have same signature
+ MATHICGB_ASSERT(sigCmp != Monoid::EqualTo);
if (sigCmp == GT)
continue;
}
@@ -363,7 +363,7 @@ bool GroebnerBasis::isSingularTopReducibleSlow
if (!ring().monomialIsDivisibleBy(polyLead, getLeadMonomial(i)))
continue;
ring().monomialDivide(polyLead, getLeadMonomial(i), multiplier);
- if (order().signatureCompare(sig, multiplier, getSignature(i)) == EQ)
+ if (monoid().compare(sig, multiplier, getSignature(i)) == EQ)
return true;
}
ring().freeMonomial(multiplier);
@@ -451,10 +451,10 @@ size_t GroebnerBasis::ratioRank(const_monomial ratio) const {
std::numeric_limits<Rank>::max());
return std::numeric_limits<Rank>::max();
} else {
- if (order().signatureCompare(ratio, getSigLeadRatio(*pos)) == EQ)
+ if (monoid().equal(ratio, getSigLeadRatio(*pos)))
return ratioRank(*pos);
MATHICGB_ASSERT(ratioRank(*pos) > 0);
-#ifdef DEBUG
+#ifdef MATHICGB_DEBUG
if (pos != mRatioSorted.begin()) {
RatioSortedType::iterator prev = pos;
--prev;
diff --git a/src/mathicgb/GroebnerBasis.hpp b/src/mathicgb/GroebnerBasis.hpp
index 5100106..5dad29e 100755
--- a/src/mathicgb/GroebnerBasis.hpp
+++ b/src/mathicgb/GroebnerBasis.hpp
@@ -7,7 +7,6 @@
#include <set>
#include "PolyRing.hpp"
#include "Poly.hpp"
-#include "FreeModuleOrder.hpp"
#include "DivisorLookup.hpp"
#include "PolyBasis.hpp"
#include "MonoProcessor.hpp"
@@ -18,19 +17,20 @@
class GroebnerBasis {
public:
+ typedef PolyRing::Monoid Monoid;
+
GroebnerBasis(
const PolyRing* R,
- FreeModuleOrder* order,
int divisorLookupType,
int monTableType,
bool preferSparseReducers
);
~GroebnerBasis();
+ const Monoid& monoid() const {return ring().monoid();}
const PolyRing& ring() const {return mBasis.ring();}
const Poly& poly(size_t index) const {return mBasis.poly(index);}
size_t size() const {return mBasis.size();}
- const FreeModuleOrder& order() const {return mBasis.order();}
// todo: stop using non-const version of basis() and then remove it.
PolyBasis& basis() {return mBasis;}
@@ -165,19 +165,19 @@ private:
std::vector<monomial> sigLeadRatio;
// true if giving each generator an integer id based on its
- // position in a sorted order of sig/lead ratios.
+ // position in a sorted order of sig-lead ratios.
static const bool mUseRatioRank = USE_RATIO_RANK;
static const bool mUseStoredRatioRank = USE_RATIO_RANK;
class RatioOrder {
public:
- RatioOrder(std::vector<monomial>& ratio, const FreeModuleOrder& order):
- mRatio(ratio), mOrder(order) {}
+ RatioOrder(std::vector<monomial>& ratio, const Monoid& monoid):
+ mRatio(ratio), mMonoid(monoid) {}
bool operator()(size_t a, size_t b) const {
- return mOrder.signatureCompare(mRatio[a], mRatio[b]) == LT;
+ return mMonoid.lessThan(mRatio[a], mRatio[b]);
}
private:
std::vector<monomial>& mRatio;
- const FreeModuleOrder& mOrder;
+ const Monoid& mMonoid;
};
typedef std::multiset<size_t, RatioOrder> RatioSortedType;
typedef size_t Rank;
@@ -198,7 +198,7 @@ inline int GroebnerBasis::ratioCompare(size_t a, size_t b) const {
if (mUseRatioRank) {
#ifdef MATHICGB_DEBUG
int const value =
- order().signatureCompare(getSigLeadRatio(a), getSigLeadRatio(b));
+ monoid().compare(getSigLeadRatio(a), getSigLeadRatio(b));
#endif
if (mRatioRanks[a] < mRatioRanks[b]) {
MATHICGB_ASSERT_NO_ASSUME(value == LT);
@@ -214,18 +214,18 @@ inline int GroebnerBasis::ratioCompare(size_t a, size_t b) const {
// A/a < B/b <=> A < (B/b)a
ring().monomialDivideToNegative(getSignature(b), getLeadMonomial(b), mTmp);
ring().monomialMultTo(mTmp, getLeadMonomial(a));
- int value = order().signatureCompare(getSignature(a), mTmp);
+ int value = monoid().compare(getSignature(a), mTmp);
MATHICGB_ASSERT(value ==
- order().signatureCompare(getSigLeadRatio(a), getSigLeadRatio(b)));
+ monoid().compare(getSigLeadRatio(a), getSigLeadRatio(b)));
return value;
}
}
inline int GroebnerBasis::StoredRatioCmp::compare(size_t be) const {
if (GroebnerBasis::mUseStoredRatioRank) {
-#ifdef DEBUG
- int value = mBasis.order().
- signatureCompare(mRatio, mBasis.getSigLeadRatio(be));
+#ifdef MATHICGB_DEBUG
+ const auto value =
+ mBasis.monoid().compare(mRatio, mBasis.getSigLeadRatio(be));
#endif
GroebnerBasis::Rank otherRank = mBasis.ratioRank(be);
if (mRatioRank < otherRank) {
@@ -240,9 +240,9 @@ inline int GroebnerBasis::StoredRatioCmp::compare(size_t be) const {
}
} else {
mBasis.ring().monomialMult(mRatio, mBasis.getLeadMonomial(be), mTmp);
- int value = mBasis.order().signatureCompare(mTmp, mBasis.getSignature(be));
+ int value = mBasis.monoid().compare(mTmp, mBasis.getSignature(be));
MATHICGB_ASSERT(value ==
- mBasis.order().signatureCompare(mRatio, mBasis.getSigLeadRatio(be)));
+ mBasis.monoid().compare(mRatio, mBasis.getSigLeadRatio(be)));
return value;
}
}
diff --git a/src/mathicgb/PairTriangle.cpp b/src/mathicgb/PairTriangle.cpp
index 86119bc..bc89984 100755
--- a/src/mathicgb/PairTriangle.cpp
+++ b/src/mathicgb/PairTriangle.cpp
@@ -64,7 +64,12 @@ namespace {
}
void PairTriangle::endColumn() {
- mOrder.sortSignatures(mPrePairs);
+ const auto& monoid = mRing.monoid();
+ const auto cmp = [&monoid](const PreSPair& a, const PreSPair& b) {
+ return monoid.lessThan(a.signature, b.signature);
+ };
+ std::sort(mPrePairs.begin(), mPrePairs.end(), cmp);
+
typedef IndexIterator<std::vector<PreSPair>::const_iterator> Iter;
mPairQueue.addColumnDescending
(Iter(mPrePairs.begin()), Iter(mPrePairs.end()));
diff --git a/src/mathicgb/PolyBasis.cpp b/src/mathicgb/PolyBasis.cpp
index 4ed5546..a7f2be5 100755
--- a/src/mathicgb/PolyBasis.cpp
+++ b/src/mathicgb/PolyBasis.cpp
@@ -6,11 +6,9 @@
PolyBasis::PolyBasis(
const PolyRing& ring,
- FreeModuleOrder& order,
std::unique_ptr<DivisorLookup> divisorLookup
):
mRing(ring),
- mOrder(order),
mDivisorLookup(std::move(divisorLookup))
{
MATHICGB_ASSERT(mDivisorLookup.get() != 0);
@@ -37,7 +35,7 @@ std::unique_ptr<Basis> PolyBasis::initialIdeal() const {
basis->insert(std::move(p));
}
}
- basis->sort(mOrder);
+ basis->sort();
return basis;
}
diff --git a/src/mathicgb/PolyBasis.hpp b/src/mathicgb/PolyBasis.hpp
index faaf360..37e6971 100755
--- a/src/mathicgb/PolyBasis.hpp
+++ b/src/mathicgb/PolyBasis.hpp
@@ -8,16 +8,17 @@
class PolyRing;
class Basis;
-class FreeModuleOrder;
class PolyBasis {
public:
- // Ring and order must live for as long as this object. divisorLookupFactory
+ typedef PolyRing::Monoid Monoid;
+
+ // Ring must live for as long as this object. divisorLookupFactory
// only needs to live for the duration of the constructor.
PolyBasis(
const PolyRing& ring,
- FreeModuleOrder& order,
- std::unique_ptr<DivisorLookup> divisorLookup);
+ std::unique_ptr<DivisorLookup> divisorLookup
+ );
// Deletes the Poly's stored in the basis.
~PolyBasis();
@@ -67,8 +68,7 @@ public:
// Returns the ambient polynomial ring of the polynomials in the basis.
const PolyRing& ring() const {return mRing;}
- // Returns the term order on the basis.
- const FreeModuleOrder& order() const {return mOrder;}
+ const Monoid& monoid() const {return ring().monoid();}
// Returns a data structure containing the lead monomial of each lead
// monomial.
@@ -219,7 +219,6 @@ private:
typedef EntryCont::const_iterator EntryCIter;
const PolyRing& mRing;
- FreeModuleOrder& mOrder;
std::unique_ptr<DivisorLookup> mDivisorLookup;
std::vector<Entry> mEntries;
};
diff --git a/src/mathicgb/SigSPairQueue.cpp b/src/mathicgb/SigSPairQueue.cpp
index 8def30e..d7859c4 100755
--- a/src/mathicgb/SigSPairQueue.cpp
+++ b/src/mathicgb/SigSPairQueue.cpp
@@ -1,5 +1,185 @@
#include "stdinc.h"
#include "SigSPairQueue.hpp"
-SigSPairQueue::~SigSPairQueue() {
+#include "GroebnerBasis.hpp"
+
+SigSPairQueue::~SigSPairQueue() {}
+
+namespace {
+ class Comparer {
+ public:
+ typedef PolyRing::Monoid Monoid;
+
+ Comparer(const Monoid& monoid): mMonoid(monoid) {}
+ bool operator()(const PreSPair& a, const PreSPair& b) const {
+ return mMonoid.lessThan(a.signature, b.signature);
+ }
+ private:
+ const Monoid& mMonoid;
+ };
+
+ // Iterator that accesses the field i based on a passed-in iterator.
+ template<class PairIterator>
+ class IndexIterator {
+ public:
+
+ typedef typename PairIterator::iterator_category iterator_category;
+ typedef decltype(reinterpret_cast<typename PairIterator::value_type*>(0)->i) value_type;
+ typedef typename PairIterator::difference_type difference_type;
+ typedef value_type* pointer;
+ typedef value_type& reference;
+
+ IndexIterator(PairIterator pairIterator): mIterator(pairIterator) {}
+ IndexIterator& operator++() {++mIterator; return *this;}
+ const value_type operator*() const {return mIterator->i;}
+ difference_type operator-(const IndexIterator<PairIterator>& it) const {
+ return mIterator - it.mIterator;
+ }
+ bool operator==(const IndexIterator<PairIterator>& it) const {
+ return mIterator == it.mIterator;
+ }
+ bool operator!=(const IndexIterator<PairIterator>& it) const {
+ return mIterator != it.mIterator;
+ }
+
+ private:
+ PairIterator mIterator;
+ };
+}
+
+
+class ConcreteSigSPairQueue : public SigSPairQueue {
+public:
+ ConcreteSigSPairQueue(GroebnerBasis const& basis):
+ mPairQueue(Configuration(basis)) {}
+
+ virtual monomial popSignature(Pairs& pairs) {
+ pairs.clear();
+ if (mPairQueue.empty())
+ return 0;
+ monomial sig = ring().allocMonomial();
+ ring().monomialCopy(mPairQueue.topPairData(), sig);
+ do {
+ pairs.push_back(mPairQueue.topPair());
+ mPairQueue.pop();
+ } while
+ (!mPairQueue.empty() && ring().monomialEQ(mPairQueue.topPairData(), sig));
+ return sig;
+ }
+
+ virtual void pushPairs(size_t pairWith, IndexSigs& pairs) {
+#ifdef DEBUG
+ monomial tmp = ring().allocMonomial();
+ for (size_t i = 0; i < pairs.size(); ++i) {
+ MATHICGB_ASSERT(pairs[i].i < columnCount());
+ mPairQueue.configuration().computePairData
+ (columnCount(), pairs[i].i, tmp);
+ MATHICGB_ASSERT(ring().monomialEQ(tmp, pairs[i].signature));
+ }
+ ring().freeMonomial(tmp);
+#endif
+
+ if (columnCount() >= std::numeric_limits<BigIndex>::max())
+ throw std::overflow_error
+ ("Too large basis element index in constructing S-pairs.");
+
+ // sort and insert new column
+ Comparer cmp(ring().monoid());
+ std::sort(pairs.begin(), pairs.end(), cmp);
+ typedef IndexIterator<std::vector<PreSPair>::const_iterator> Iter;
+ mPairQueue.addColumnDescending(Iter(pairs.begin()), Iter(pairs.end()));
+
+ // free signatures
+ std::vector<PreSPair>::iterator end = pairs.end();
+ for (std::vector<PreSPair>::iterator it = pairs.begin(); it != end; ++it)
+ ring().freeMonomial(it->signature);
+ pairs.clear();
+ }
+
+ virtual std::string name() const {return "todo";}
+
+ virtual size_t memoryUse() const {return mPairQueue.getMemoryUse();}
+
+ virtual size_t pairCount() const {return mPairQueue.pairCount();}
+
+ virtual size_t columnCount() const {return mPairQueue.columnCount();}
+
+private:
+ ConcreteSigSPairQueue(const ConcreteSigSPairQueue&); // not available
+ void operator=(const ConcreteSigSPairQueue&); // not available
+
+ // Configuration of mathic::PairTriangle for use with signature queues.
+ class Configuration {
+ public:
+ Configuration(GroebnerBasis const& basis): mBasis(basis) {}
+
+ typedef monomial PairData;
+ void computePairData(size_t col, size_t row, monomial sig) {
+ MATHICGB_ASSERT(mBasis.ratioCompare(col, row) != EQ);
+ // ensure that ratio(col) > ratio(row)
+ if (mBasis.ratioCompare(col, row) == LT)
+ std::swap(col, row);
+ mBasis.ring().monomialFindSignature
+ (mBasis.getLeadMonomial(col),
+ mBasis.getLeadMonomial(row),
+ mBasis.getSignature(col), sig);
+ }
+
+ typedef bool CompareResult;
+ bool compare(int colA, int rowA, const_monomial a,
+ int colB, int rowB, const_monomial b) const {
+ return mBasis.ring().monoid().lessThan(b, a);
+ }
+ bool cmpLessThan(bool v) const {return v;}
+
+ GroebnerBasis const& basis() const {return mBasis;}
+
+ private:
+ GroebnerBasis const& mBasis;
+ };
+
+ // the compiler should be able to resolve these accessors into a direct
+ // offset as though these were member variables.
+ const GroebnerBasis& basis() const {
+ return mPairQueue.configuration().basis();
+ }
+ PolyRing const& ring() const {return basis().ring();}
+
+ mathic::PairQueue<Configuration> mPairQueue;
+ friend struct
+ mathic::PairQueueNamespace::ConstructPairDataFunction<Configuration>;
+ friend struct
+ mathic::PairQueueNamespace::DestructPairDataFunction<Configuration>;
+};
+
+namespace mathic {
+ namespace PairQueueNamespace {
+ template<>
+ struct ConstructPairDataFunction<ConcreteSigSPairQueue::Configuration> {
+ inline static void function
+ (void* memory, Index col, Index row, ConcreteSigSPairQueue::Configuration& conf) {
+ MATHICGB_ASSERT(memory != 0);
+ MATHICGB_ASSERT(col > row);
+ monomial* pd = new (memory) monomial
+ (conf.basis().ring().allocMonomial());
+ conf.computePairData(col, row, *pd);
+ }
+ };
+
+ template<>
+ struct DestructPairDataFunction<ConcreteSigSPairQueue::Configuration> {
+ inline static void function
+ (monomial* pd, Index col, Index row, ConcreteSigSPairQueue::Configuration& conf) {
+ MATHICGB_ASSERT(pd != 0);
+ MATHICGB_ASSERT(col > row);
+ conf.basis().ring().freeMonomial(*pd);
+ }
+ };
+ }
+}
+
+std::unique_ptr<SigSPairQueue> SigSPairQueue::create(
+ GroebnerBasis const& basis
+) {
+ return make_unique<ConcreteSigSPairQueue>(basis);
}
diff --git a/src/mathicgb/SigSPairQueue.hpp b/src/mathicgb/SigSPairQueue.hpp
index 2ec34e1..3bba62d 100755
--- a/src/mathicgb/SigSPairQueue.hpp
+++ b/src/mathicgb/SigSPairQueue.hpp
@@ -13,14 +13,16 @@ struct PreSPair {
monomial signature;
};
+class GroebnerBasis;
+
// A priority queue on S-pairs where the priority is based on a
// signature as in signature Grobner basis algorithms. The class is
// not responsible for eliminating S-pairs or doing anything beyond
// order the S-pairs.
-//
-// You create these queues from a module term order.
class SigSPairQueue {
public:
+ typedef PolyRing::Monoid Monoid;
+
virtual ~SigSPairQueue();
typedef std::pair<size_t, size_t> Pair;
@@ -64,6 +66,8 @@ public:
// Returns number of bytes of memory used.
virtual size_t memoryUse() const = 0;
+
+ static std::unique_ptr<SigSPairQueue> create(GroebnerBasis const& basis);
};
#endif
diff --git a/src/mathicgb/SigSPairs.cpp b/src/mathicgb/SigSPairs.cpp
index dc95301..92759a8 100755
--- a/src/mathicgb/SigSPairs.cpp
+++ b/src/mathicgb/SigSPairs.cpp
@@ -27,8 +27,8 @@ SigSPairs::SigSPairs(
GB(GB0),
mReducer(reducer),
mPostponeKoszuls(postponeKoszuls),
- mQueue(GB->order().createSigSPairQueue(*GB)) {
-}
+ mQueue(SigSPairQueue::create(*GB))
+{}
SigSPairs::~SigSPairs()
{
diff --git a/src/mathicgb/SignatureGB.cpp b/src/mathicgb/SignatureGB.cpp
index de915a5..897592d 100755
--- a/src/mathicgb/SignatureGB.cpp
+++ b/src/mathicgb/SignatureGB.cpp
@@ -37,7 +37,7 @@ SignatureGB::SignatureGB(
stats_relativelyPrimeEliminated(0),
stats_pairsReduced(0),
stats_nsecs(0.0),
- GB(make_unique<GroebnerBasis>(R, F.get(), divlookup_type, montable_type, preferSparseReducers)),
+ GB(make_unique<GroebnerBasis>(R, divlookup_type, montable_type, preferSparseReducers)),
mKoszuls(R->monoid()),
Hsyz(MonomialTableArray::make(R, montable_type, basis.size(), !mPostponeKoszul)),
Hsyz2(MonomialTableArray::make(R, montable_type, basis.size(), !mPostponeKoszul)),
diff --git a/src/mathicgb/TypicalReducer.cpp b/src/mathicgb/TypicalReducer.cpp
index 9fb2365..a6436a0 100755
--- a/src/mathicgb/TypicalReducer.cpp
+++ b/src/mathicgb/TypicalReducer.cpp
@@ -183,8 +183,10 @@ std::unique_ptr<Poly> TypicalReducer::classicReduce
size_t reducer = basis.classicReducer(v.monom);
if (reducer == static_cast<size_t>(-1)) { // no reducer found
- MATHICGB_ASSERT(result->isZero() ||
- basis.order().signatureCompare(v.monom, result->backMonomial()) == LT);
+ MATHICGB_ASSERT(
+ result->isZero() ||
+ basis.monoid().lessThan(v.monom, result->backMonomial())
+ );
result->appendTerm(v.coeff, v.monom);
removeLeadTerm();
} else { // reduce by reducer
diff --git a/src/test/F4MatrixBuilder.cpp b/src/test/F4MatrixBuilder.cpp
index 93d62fc..0ac2828 100755
--- a/src/test/F4MatrixBuilder.cpp
+++ b/src/test/F4MatrixBuilder.cpp
@@ -3,7 +3,6 @@
#include "mathicgb/Poly.hpp"
#include "mathicgb/PolyRing.hpp"
#include "mathicgb/F4MatrixBuilder.hpp"
-#include "mathicgb/FreeModuleOrder.hpp"
#include "mathicgb/Basis.hpp"
#include "mathicgb/PolyBasis.hpp"
#include "mathicgb/io-util.hpp"
@@ -22,8 +21,7 @@ namespace {
BuilderMaker():
mRing(ringFromString("101 6 1\n1 1 1 1 1 1")),
mIdeal(*mRing),
- mOrder(FreeModuleOrder::makeOrder(1, *mIdeal.getPolyRing())),
- mBasis(*mRing, *mOrder, DivisorLookup::makeFactory(*mRing, 1)->create(true, true)) {
+ mBasis(*mRing, DivisorLookup::makeFactory(*mRing, 1)->create(true, true)) {
}
const Poly& addBasisElement(const std::string& str) {
@@ -45,7 +43,6 @@ namespace {
private:
std::unique_ptr<PolyRing> mRing;
Basis mIdeal;
- std::unique_ptr<FreeModuleOrder> mOrder;
PolyBasis mBasis;
std::unique_ptr<F4MatrixBuilder> mBuilder;
};
--
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