[mathicgb] 290/393: Simplified and improved the pre/postprocessing code for module monomial ordering.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:22 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 765ddd1827d9d515122a954aeddcb165926285bb
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Fri Apr 19 18:35:08 2013 -0400

    Simplified and improved the pre/postprocessing code for module monomial ordering.
---
 src/cli/SigGBAction.cpp        |   4 +-
 src/mathicgb/GroebnerBasis.cpp |  19 ++-----
 src/mathicgb/GroebnerBasis.hpp |  11 ++--
 src/mathicgb/MonoMonoid.hpp    |  21 +++++---
 src/mathicgb/MonoProcessor.hpp | 118 +++++++++++++++++++++++++++++++++++++++++
 src/mathicgb/SignatureGB.cpp   |  48 +++++++----------
 src/mathicgb/SignatureGB.hpp   |  15 +++---
 src/test/gb-test.cpp           |   4 +-
 8 files changed, 169 insertions(+), 71 deletions(-)

diff --git a/src/cli/SigGBAction.cpp b/src/cli/SigGBAction.cpp
index d257ac2..5d19316 100755
--- a/src/cli/SigGBAction.cpp
+++ b/src/cli/SigGBAction.cpp
@@ -57,11 +57,9 @@ void SigGBAction::performAction() {
     ideal = Ideal::parse(inputFile);
   }
   std::unique_ptr<PolyRing const> ring(&(ideal->ring()));
-  if (mModuleOrder.value() == 2 || mModuleOrder.value() == 4 || mModuleOrder.value() == 6)
-    ideal->reverse();
 
   SignatureGB alg(
-    *ideal,
+    std::move(*ideal),
     mModuleOrder.value(),
     Reducer::reducerType(mGBParams.mReducer.value()),
     mGBParams.mDivisorLookup.value(),
diff --git a/src/mathicgb/GroebnerBasis.cpp b/src/mathicgb/GroebnerBasis.cpp
index d6c0d2c..a22d1f0 100755
--- a/src/mathicgb/GroebnerBasis.cpp
+++ b/src/mathicgb/GroebnerBasis.cpp
@@ -407,22 +407,9 @@ void GroebnerBasis::dump() const
   display(std::cerr);
 }
 
-void GroebnerBasis::unschreyer(const std::vector<Monomial>& leads) {
-  for (size_t i = 0; i < mSignatures.size(); ++i) {
-    auto sig = mSignatures[i];
-    auto c = ring().monomialGetComponent(sig);
-    MATHICGB_ASSERT(c < leads.size());
-    ring().monomialDivide(sig, leads[c], sig);
-  }
-}
-
-void GroebnerBasis::reverseComponents(const size_t componentCount) {
-  for (size_t i = 0; i < mSignatures.size(); ++i) {
-    auto sig = mSignatures[i];
-    auto c = ring().monomialGetComponent(sig);
-    MATHICGB_ASSERT(c < componentCount);
-    ring().monomialChangeComponent(sig, componentCount - 1 - c);
-  }
+void GroebnerBasis::postprocess(const MonoProcessor<PolyRing::Monoid>& processor) {
+  for (size_t i = 0; i < mSignatures.size(); ++i)
+    processor.postprocess(mSignatures[i]);
 }
 
 size_t GroebnerBasis::getMemoryUse() const
diff --git a/src/mathicgb/GroebnerBasis.hpp b/src/mathicgb/GroebnerBasis.hpp
index 598c5de..5100106 100755
--- a/src/mathicgb/GroebnerBasis.hpp
+++ b/src/mathicgb/GroebnerBasis.hpp
@@ -10,6 +10,7 @@
 #include "FreeModuleOrder.hpp"
 #include "DivisorLookup.hpp"
 #include "PolyBasis.hpp"
+#include "MonoProcessor.hpp"
 
 #ifndef USE_RATIO_RANK
 #define USE_RATIO_RANK true
@@ -102,13 +103,9 @@ public:
   // and returns LT, EQ or GT.
   inline int ratioCompare(size_t a, size_t b) const;
 
-  /// Divides all signatures ae_i by leads[i]. This currently breaks
-  /// all sorts of internal invariants - it's a temporary hack.
-  void unschreyer(const std::vector<Monomial>& leads);
-
-  // Replaces component i with componentCount - 1 - i. As unschreyer,
-  // this breaks internval invariants and should be replaced.
-  void reverseComponents(const size_t componentCount);
+  /// Post processes all signatures. This currently breaks all sorts
+  /// of internal invariants - it's supposed to be a temporary hack.
+  void postprocess(const MonoProcessor<PolyRing::Monoid>& processor);
 
   class StoredRatioCmp {
   public:
diff --git a/src/mathicgb/MonoMonoid.hpp b/src/mathicgb/MonoMonoid.hpp
index 9899a79..c04113d 100755
--- a/src/mathicgb/MonoMonoid.hpp
+++ b/src/mathicgb/MonoMonoid.hpp
@@ -253,6 +253,12 @@ public:
     return !(*this == monoid);
   }
 
+  /// Returns true if higher component is considered greater when
+  /// comparing module monomials. Only relevant once actually
+  /// considering the component. This is only relevant for module
+  /// monomials.
+  bool componentsAscending() const {return mLexBaseOrder;}
+
   /// Returns the number of variables. This is also the number of
   /// exponents in the exponent vector of a monomial.
   VarIndex varCount() const {return mVarCount;}
@@ -1069,6 +1075,8 @@ public:
 
   class MonoRef {
   public:
+    MonoRef(const MonoRef& mono): mMono(mono.ptr()) {}
+
     MonoPtr ptr() const {return mMono;}
 
     operator ConstMonoRef() const {return *static_cast<ConstMonoPtr>(mMono);}
@@ -1085,6 +1093,7 @@ public:
 
   class ConstMonoRef {
   public:
+    ConstMonoRef(const ConstMonoRef& mono): mMono(mono.ptr()) {}
     ConstMonoRef(const Mono& mono): mMono(mono.ptr()) {
       MATHICGB_ASSERT(!mono.isNull());
     }
@@ -1170,14 +1179,14 @@ public:
       bool operator!=(const const_iterator& it) const {return mIt != it.mIt;}
 
       ConstMonoRef operator*() {
-	MATHICGB_ASSERT(debugValid());
-	return *ConstMonoPtr(&*mIt);
+        MATHICGB_ASSERT(debugValid());
+        return *ConstMonoPtr(&*mIt);
       }
 
       const_iterator operator++() {
-	MATHICGB_ASSERT(debugValid());
-	mIt += mEntriesPerMono;
-	return *this;
+        MATHICGB_ASSERT(debugValid());
+        mIt += mEntriesPerMono;
+        return *this;
       }
 
     private:
@@ -1186,7 +1195,7 @@ public:
 
       const_iterator(
         typename RawVector::const_iterator it,
-	size_t entryCount
+        size_t entryCount
       ): mIt(it), mEntriesPerMono(entryCount) {}
       
       typename RawVector::const_iterator mIt;
diff --git a/src/mathicgb/MonoProcessor.hpp b/src/mathicgb/MonoProcessor.hpp
new file mode 100755
index 0000000..0881764
--- /dev/null
+++ b/src/mathicgb/MonoProcessor.hpp
@@ -0,0 +1,118 @@
+#ifndef MATHICGB_MONO_PROCESSOR_GUARD
+#define MATHICGB_MONO_PROCESSOR_GUARD
+
+#include "MonoMonoid.hpp"
+
+/// Does pre- and post-processing of monomials to implement monomial
+/// orders not directly supported by the monoid. This is so far only
+/// relevant for module monomials.
+///
+/// todo: distinguish monomials from module monomials using two
+/// different monoids.
+template<class Monoid>
+class MonoProcessor;
+
+template<class M>
+class MonoProcessor {
+public:
+  typedef M Monoid;
+  typedef typename Monoid::VarIndex VarIndex;
+  typedef typename Monoid::MonoVector MonoVector;
+  typedef typename Monoid::MonoRef MonoRef;
+  typedef typename Monoid::ConstMonoRef ConstMonoRef;
+  typedef typename Monoid::ConstMonoPtr ConstMonoPtr;
+
+  static_assert(Monoid::HasComponent, "");
+
+  MonoProcessor(
+    bool componentsAscendingDesired, // todo: replace with MonoOrder
+    VarIndex componentCount, // todo: replace with MonoOrder
+    const Monoid& monoid,
+    MonoVector&& moduleAdjustments
+  ):
+    mMonoid(monoid),
+    mComponentsAscendingDesired(componentsAscendingDesired),
+    //mComponentsAscendingDesired(order.componentsAscendingDesired),
+    mComponentCount(componentCount),
+    //mComponentCount(order.componentCount()),
+    mModuleAdjustmentsMemory(std::move(moduleAdjustments))
+  {
+    MATHICGB_ASSERT(mModuleAdjustmentsMemory.monoid() == this->monoid());
+    MATHICGB_ASSERT(mModuleAdjustmentsMemory.empty() ||
+      mModuleAdjustmentsMemory.size() == this->componentCount());
+    // todo: add a component count to the monoid and get it from there
+    // instead of storing it here.
+
+    for (
+      auto it = mModuleAdjustmentsMemory.begin();
+      it != mModuleAdjustmentsMemory.end();
+      ++it
+    ) {
+      // in the absence of a separate monoid for (non-module) monomials,
+      // at least we can check that the component is zero.
+      MATHICGB_ASSERT(this->monoid().component(*it) == 0);
+
+      // todo: there should be a better way of indexing into a
+      // MonoVector.
+      mModuleAdjustments.emplace_back((*it).ptr());
+    }
+  }
+    
+
+  void preprocess(MonoRef mono) const {
+    if (hasModuleAdjustments())
+      monoid().multiplyInPlace(moduleAdjustment(mono), mono);
+    if (needToReverseComponents())
+      reverseComponent(mono);
+  }
+
+  void postprocess(MonoRef mono) const {
+    if (needToReverseComponents())
+      reverseComponent(mono);
+    if (hasModuleAdjustments()) {
+      MATHICGB_ASSERT(monoid().divides(moduleAdjustment(mono), mono));
+      monoid().divideInPlace(moduleAdjustment(mono), mono);
+    }
+  }
+
+  bool processingNeeded() const {
+    return needToReverseComponents() || hasModuleAdjustments();
+  }
+
+  bool needToReverseComponents() const {
+    return Monoid::HasComponent &&
+      mComponentsAscendingDesired != mMonoid.componentsAscending();
+  }
+
+  bool hasModuleAdjustments() const {
+    return !mModuleAdjustments.empty();
+  }
+
+  VarIndex componentCount() const {return mComponentCount;}
+  const Monoid& monoid() const {return mMonoid;}
+
+private:
+  void operator==(const MonoProcessor&) const; // not available
+
+  void reverseComponent(MonoRef mono) const {
+    const auto component = monoid().component(mono);
+    const auto newComponent = mComponentCount - 1 - component;
+    monoid().setComponent(newComponent, mono);
+  }
+
+  ConstMonoRef moduleAdjustment(ConstMonoRef mono) const {
+    MATHICGB_ASSERT(hasModuleAdjustments());
+    const auto component = monoid().component(mono);
+    MATHICGB_ASSERT(component < componentCount());
+    MATHICGB_ASSERT(mModuleAdjustments.size() == componentCount());
+    return *mModuleAdjustments[component];
+  }
+
+  const Monoid& mMonoid;
+  const bool mComponentsAscendingDesired;
+  const VarIndex mComponentCount;
+  MonoVector mModuleAdjustmentsMemory;
+  std::vector<ConstMonoPtr> mModuleAdjustments;
+};
+
+#endif
diff --git a/src/mathicgb/SignatureGB.cpp b/src/mathicgb/SignatureGB.cpp
index b008787..b0dd13c 100755
--- a/src/mathicgb/SignatureGB.cpp
+++ b/src/mathicgb/SignatureGB.cpp
@@ -13,7 +13,7 @@
 int tracingLevel = 0;
 
 SignatureGB::SignatureGB(
-  const Ideal& ideal,
+  Ideal&& ideal,
   FreeModuleOrderType typ,
   Reducer::ReducerType reductiontyp,
   int divlookup_type,
@@ -42,21 +42,24 @@ SignatureGB::SignatureGB(
   Hsyz(MonomialTableArray::make(R, montable_type, ideal.size(), !mPostponeKoszul)),
   Hsyz2(MonomialTableArray::make(R, montable_type, ideal.size(), !mPostponeKoszul)),
   reducer(Reducer::makeReducer(reductiontyp, *R)),
-  SP(make_unique<SigSPairs>(R, F.get(), GB.get(), Hsyz.get(), reducer.get(), mPostponeKoszul, mUseBaseDivisors, useSingularCriterionEarly, queueType)),
-  mReverseComponents(typ == 2 || typ == 4 || typ == 6),
-  mDoSchreyer(typ == 5 || typ == 4 || typ == 3 || typ == 2 || typ == 6 || typ == 7),
-  mComponentCount(ideal.size())
+  SP(make_unique<SigSPairs>(R, F.get(), GB.get(), Hsyz.get(), reducer.get(), mPostponeKoszul, mUseBaseDivisors, useSingularCriterionEarly, queueType))
 {
+  MonoVector schreyer(monoid());
+  if (typ == 5 || typ == 4 || typ == 3 || typ == 2 || typ == 6 || typ == 7)
+    for (size_t gen = 0; gen < ideal.size(); ++gen)
+      schreyer.push_back(ideal.getPoly(gen)->getLeadMonomial());
+  mProcessor = make_unique<MonoProcessor<Monoid>>(
+    typ == 2 || typ == 4 || typ == 6,
+    ideal.size(),
+    monoid(),
+    std::move(schreyer)
+  );
+
   // Populate GB
   for (size_t j = 0; j < ideal.size(); j++)
     GB->addComponent();
 
-  if (mDoSchreyer)
-    mSchreyerTerms.resize(ideal.size());
-
-  for (size_t j = 0; j < ideal.size(); j++) {
-    int i = !mReverseComponents ? j : ideal.size() - 1 - j;
-
+  for (size_t i = 0; i < ideal.size(); i++) {
     Poly *g = new Poly(*R);
     ideal.getPoly(i)->copy(*g);
     g->makeMonic();
@@ -64,12 +67,7 @@ SignatureGB::SignatureGB(
     monomial sig = 0;
     sig = R->allocMonomial();
     R->monomialEi(i, sig);
-    if (mDoSchreyer) {
-      auto lead = R->allocMonomial();
-      R->monomialCopy(g->getLeadMonomial(), lead);
-      mSchreyerTerms[i] = lead;
-      R->monomialMult(sig, g->getLeadMonomial(), sig);
-    }
+    mProcessor->preprocess(sig);
     {
       std::unique_ptr<Poly> autoG(g);
       GB->insert(sig, std::move(autoG));
@@ -134,24 +132,14 @@ void SignatureGB::computeGrobnerBasis()
   stats_nsecs = mTimer.getMilliseconds() / 1000.0;
   //GB->displayBrief(out);
 
-  if (mDoSchreyer)
-    GB->unschreyer(mSchreyerTerms);
-  if (mReverseComponents)
-    GB->reverseComponents(mComponentCount);
-  if (mDoSchreyer || mReverseComponents) {
+  if (mProcessor->processingNeeded()) {
+    GB->postprocess(*mProcessor);
     std::vector<const_monomial> v;
     Hsyz->getMonomials(v);
     for (size_t i = 0; i < v.size(); ++i) {
       auto sig = R->allocMonomial();
       R->monomialCopy(v[i], sig);
-      auto c = R->monomialGetComponent(sig);
-      MATHICGB_ASSERT(c < mComponentCount);
-      if (mDoSchreyer) {
-        MATHICGB_ASSERT(mComponentCount == mSchreyerTerms.size());
-        R->monomialDivide(sig, mSchreyerTerms[c], sig);
-      }
-      if (mReverseComponents)
-        R->monomialChangeComponent(sig, mComponentCount - 1 - c);
+      mProcessor->postprocess(sig);
       Hsyz2->insert(sig, 0);
     }
   }
diff --git a/src/mathicgb/SignatureGB.hpp b/src/mathicgb/SignatureGB.hpp
index 647c56a..f7e95c3 100755
--- a/src/mathicgb/SignatureGB.hpp
+++ b/src/mathicgb/SignatureGB.hpp
@@ -15,6 +15,7 @@
 #include "Reducer.hpp"
 #include "KoszulQueue.hpp"
 #include "SPairs.hpp"
+#include "MonoProcessor.hpp"
 #include <map>
 
 class SigSPairs;
@@ -22,8 +23,11 @@ class DivisorLookup;
 
 class SignatureGB {
 public:
+  typedef PolyRing::Monoid Monoid;
+  typedef Monoid::MonoVector MonoVector;
+
   SignatureGB(
-    const Ideal& ideal,
+    Ideal&& ideal,
     FreeModuleOrderType typ,
     Reducer::ReducerType reductiontyp,
     int divlookup_type,
@@ -43,7 +47,7 @@ public:
   unsigned long long getSingularReductionCount() const;
 
   GroebnerBasis* getGB() { return GB.get(); }
-  MonomialTableArray* getSyzTable() { return (!mDoSchreyer && !mReverseComponents) ? Hsyz.get() : Hsyz2.get(); }
+  MonomialTableArray* getSyzTable() { return mProcessor->processingNeeded() ? Hsyz2.get() : Hsyz.get(); }
   SigSPairs* getSigSPairs() { return SP.get(); }
 
   size_t getMemoryUse() const;
@@ -60,6 +64,8 @@ public:
     mPrintInterval = reductions;
   }
 
+  const Monoid& monoid() const {return R->monoid();}
+
 private:
   unsigned int mBreakAfter;
   unsigned int mPrintInterval;
@@ -103,10 +109,7 @@ private:
   std::unique_ptr<MonomialTableArray> Hsyz2;
   std::unique_ptr<Reducer> reducer;
   std::unique_ptr<SigSPairs> SP;
-  std::vector<monomial> mSchreyerTerms;
-  const bool mReverseComponents;
-  const bool mDoSchreyer;
-  const size_t mComponentCount;
+  std::unique_ptr<MonoProcessor<Monoid>> mProcessor;
 };
 
 #endif
diff --git a/src/test/gb-test.cpp b/src/test/gb-test.cpp
index 3b5b2ba..6eca92b 100755
--- a/src/test/gb-test.cpp
+++ b/src/test/gb-test.cpp
@@ -307,10 +307,8 @@ spairQueue	reducerType	divLookup	monTable	buchberger	postponeKoszul	useBaseDivis
         << reducerType << ' ' << divLookup << ' '
         << monTable << ' ' << postponeKoszul << ' ' << useBaseDivisors;
     } else {
-      if (freeModuleOrder == 2 || freeModuleOrder == 4 || freeModuleOrder == 6)
-        I->reverse();
      SignatureGB basis
-        (*I, freeModuleOrder, Reducer::reducerType(reducerType),
+       (std::move(*I), freeModuleOrder, Reducer::reducerType(reducerType),
          divLookup, monTable, postponeKoszul, useBaseDivisors,
          preferSparseReducers, useSingularCriterionEarly, spairQueue);
       basis.computeGrobnerBasis();

-- 
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