[mathicgb] 297/393: MonoOrder is improved, now immutable and used by MonoMonoid::readMonoid.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:25 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 2b0bdf1526043f3757903771eb501369c7c5aad3
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Tue Apr 23 11:36:26 2013 +0200

    MonoOrder is improved, now immutable and used by MonoMonoid::readMonoid.
---
 src/mathicgb/MonoMonoid.hpp |  25 ++++--
 src/mathicgb/MonoOrder.hpp  | 190 ++++++++++++++++++++++++++++++--------------
 2 files changed, 150 insertions(+), 65 deletions(-)

diff --git a/src/mathicgb/MonoMonoid.hpp b/src/mathicgb/MonoMonoid.hpp
index 9e2ba63..3803f53 100755
--- a/src/mathicgb/MonoMonoid.hpp
+++ b/src/mathicgb/MonoMonoid.hpp
@@ -136,13 +136,16 @@ public:
 
   MonoMonoid(MonoOrder<Exponent>& order):
     mVarCount(order.varCount()),
-    mGradingCount(gradingCount()),
+    mGradingCount(order.gradingCount()),
     mOrderIndexBegin(HasComponent + mVarCount),
     mOrderIndexEnd(mOrderIndexBegin + StoreOrder * mGradingCount),
     mEntryCount // todo: use max here
       (mOrderIndexEnd + StoreHash == 0 ? 1 : mOrderIndexEnd + StoreHash),
     mHashCoefficients(mVarCount),
-    mGradingIsTotalDegreeRevLex(order.gradingIsTotalDegreeRevLex()),
+    mGradingIsTotalDegreeRevLex(
+      order.baseOrder() == MonoOrder<Exponent>::RevLexBaseOrder &&
+      order.isTotalDegree()
+    ),
     mGradings(),
     mLexBaseOrder(order.baseOrder() == MonoOrder<Exponent>::LexBaseOrder),
     mPool(*this)
@@ -152,11 +155,12 @@ public:
       // give smaller monomials, but we need bigger degrees to give
       // bigger monomials.
       auto& gradings = order.gradings();
-      MATHICGB_ASSERT(varCount == 0 || gradings.size() % varCount == 0);
-      MATHICGB_ASSERT(mLexBaseOrder || (varCount == 0) == (gradings.empty()));
+      mGradings.resize(gradings.size());
+      MATHICGB_ASSERT(varCount() == 0 || gradings.size() % varCount() == 0);
+      MATHICGB_ASSERT(mLexBaseOrder || (varCount() == 0) == (gradings.empty()));
 
       for (VarIndex grading = 0; grading < gradingCount(); ++grading) {
-        for (VarIndex var = 0; var < varCount; ++var) {
+        for (VarIndex var = 0; var < varCount(); ++var) {
           auto w = gradings[gradingsOppositeRowIndex(grading, var)];
           if (!mLexBaseOrder)
             w = -w;
@@ -166,7 +170,7 @@ public:
     }
 
     std::srand(0); // To use the same hash coefficients every time.
-    for (VarIndex var = 0; var < varCount; ++var)
+    for (VarIndex var = 0; var < varCount(); ++var)
       mHashCoefficients[var] = static_cast<HashValue>(std::rand());      
 
     MATHICGB_ASSERT(debugAssertValid());
@@ -1741,6 +1745,15 @@ auto MonoMonoid<E, HC, SH, SO>::readMonoid(std::istream& in) -> MonoMonoid {
     in >> e;
     gradings[w] = static_cast<Exponent>(e);
   }
+  typedef MonoOrder<Exponent> Order;
+  Order order(
+    varCount,
+    std::move(gradings),
+    lexBaseOrder ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+    Order::ComponentAfterBaseOrder
+  );
+  return MonoMonoid(order);
+
   return MonoMonoid(varCount, lexBaseOrder, gradings);
 }
 
diff --git a/src/mathicgb/MonoOrder.hpp b/src/mathicgb/MonoOrder.hpp
index 93c615f..accd166 100755
--- a/src/mathicgb/MonoOrder.hpp
+++ b/src/mathicgb/MonoOrder.hpp
@@ -8,7 +8,8 @@
 /// actual comparisons.
 ///
 /// You can extend the functionality for ordering offered here for
-/// module mononials by pre- and post-processing. See MonoProcessor.
+/// module mononials by pre- and post-processing of monomials. See
+/// MonoProcessor.
 template<class Weight>
 class MonoOrder;
 
@@ -18,80 +19,151 @@ public:
   typedef W Weight;
   typedef size_t VarIndex;
 
-  MonoOrder(const VarIndex varCount):
+  static const size_t ComponentAfterBaseOrder = static_cast<size_t>(-1);
+
+  enum BaseOrder {
+    /// Lexicographic order with x0 < x1 < ... < x_n.
+    LexBaseOrder = 0,
+
+    /// Reverse lexicographic order with x0 > x1 > ... > x_n.
+    RevLexBaseOrder = 1
+  };
+
+  /// Same as MonoOrder(varCount, varOrder, gradings, componentBefore)
+  /// where gradings has a single row of varCount 1's.
+  MonoOrder(
+    const VarIndex varCount,
+    const BaseOrder baseOrder = RevLexBaseOrder,
+    const size_t componentBefore = ComponentAfterBaseOrder
+  ):
     mVarCount(varCount),
-    mGradings(false),
-    mTotalDegreeGrading(true),
-    mBaseOrder(RevLexBaseOrder),
-    mComponentBefore(ComponentLast),
-    mUseSchreyerOrder(true),
-    mComponentsAscendingDesired(true)
+    mGradings(varCount, 1),
+    mBaseOrder(baseOrder),
+    mComponentBefore(ComponentAfterBaseOrder)
   {}
 
-  const VarIndex varCount() const {return mVarCount;}
+  /// The specified base order is graded by the gradings matrix.
+  ///
+  /// The layout of the gradings matrix is row-major. For comparisons,
+  /// the degree with respect to the first row is considered first,
+  /// then the degree with respect to the second row and so on. The
+  /// base order is used as a tie-breaker. The gradings vector can be
+  /// empty. The order must be a monomial order - in particular, 1
+  /// must be strictly less than all other monomials.
+  ///
+  /// For module monomials, the component is considered too. When the
+  /// component is considered depens on componentBefore. If
+  /// componentBefore == 0 then the component is considered before
+  /// anything else. If componentBefore < gradingCount(), then the
+  /// component is considered before the grading with index
+  /// componentBefore and after the grading with index componentBefore
+  /// - 1. If componentBefore == gradingCount(), then the component is
+  /// considered after all gradings and before the base order. If
+  /// componentBefore = ComponentAfterBaseOrder then the component is
+  /// considered after everything else.
+  ///
+  /// The ordering represented by this object will be equivalent to
+  /// the specified order, but it may be encoded differently. For
+  /// example, if varCount == 0, then all orders are equivalent so all
+  /// the other parameters are ignored and the encoding will be chosen
+  /// to be the minimal-overhead one: ungraded lex with component
+  /// considered last (do not depend on this particular choice - it
+  /// may change). Therefore, you cannot count on any setting of this
+  /// order to match what you passed in as a parameter.
+  ///
+  /// If the ordering you hav specified is not a monomial order, then
+  /// the only guarantee in terms of encoding is that isMonomialOrder
+  /// will return false.
+  MonoOrder(
+    const VarIndex varCount,
+    std::vector<Weight>&& gradings,
+    const BaseOrder baseOrder = RevLexBaseOrder,
+    const size_t componentBefore = ComponentAfterBaseOrder
+  ):
+    mVarCount(varCount),
+    mGradings(std::move(gradings)),
+    mBaseOrder(baseOrder),
+    mComponentBefore(componentBefore)
+  {}
 
-  /// Set the matrix that defines the order. The entry layout is row
-  /// major. The first row is considered first, then the second row
-  /// and so on.
-  void setGradings(std::vector<Weight>&& gradings) {
-    MATHICGB_ASSERT(varCount() > 0 || gradings.empty());
-    MATHICGB_ASSERT(varCount() == 0 || gradings.size() % varCount() == 0);
-    mGradings = std::move(gradings);
-    mTotalDegreeGrading = false;
-  }
+  const VarIndex varCount() const {return mVarCount;}
 
-  /// As calling setGradings with a vector of varCount() 1's.
-  void setTotalDegreeGrading() const {
-    mGradings.clear();
-    mTotalDegreeGrading = true;
+  /// Returns the number of rows in the grading vector.
+  size_t gradingCount() const {
+    return varCount() == 0 ? 0 : mGradings.size() / varCount();
   }
 
-  std::vector<Weight>& gradings() {
-    if (mTotalDegreeGrading && mGradings.empty())
-      mGradings.resize(varCount(), 1);
-    return mGradings;
-  }
+  /// Returns the grading matrix in row-major layout.
+  const std::vector<Weight>& gradings() {return mGradings;}
 
-  bool gradingIsTotalDegreeRevLex() const {
-    return baseOrder() == RevLexBaseOrder && mTotalDegreeGrading;
+  /// Returns true if the grading matrix is a single row of 1's.
+  bool isTotalDegree() const {
+    if (varCount() == 0 || mGradings.size() != varCount())
+      return false;
+    for (VarIndex var = 0; var < varCount(); ++var)
+      if (mGradings[var] != 1)
+        return false;
+    return true;
   }
 
-  /// Returns the number of rows in the grading vector.
-  size_t gradingCount() const {return mGradings.size() / varCount();}
-
-  enum BaseOrder {
-    LexBaseOrder = 0,
-    RevLexBaseOrder = 1
-  };
-  /// Set the order to use as a tie-braker for the grading matrix.
-  void setBaseOrder(BaseOrder baseOrder) {mBaseOrder = baseOrder;}
   BaseOrder baseOrder() const {return mBaseOrder;}
 
-  static const size_t ComponentLast = static_cast<size_t>(-1);
-
-  /// The component is considered before row (grading) and after row
-  /// (grading - 1) in the order matrix. If grading == 0 then the
-  /// component is considered before anything else. If grading ==
-  /// gradingCount() then grading is considered after the grading
-  /// matrix but before the base order. If grading is ComponentLast,
-  /// then the component is used as the final tie breaker after both
-  /// the grading matrix and the base order. All values of this setting
-  /// except for ComponentLast imply overhead equivalent to one extra row
-  /// in the grading matrix even for monoids without components.
-  /// ComponentLast has no overhead.
-  void setComponentBefore(const size_t grading) const {
-    MATHICGB_ASSERT(grading == ComponentLast || grading <= gradingCount);
-    mComponentBefore = grading;
+  /// Returns true if the order is a monomial order. A monomial order
+  /// is a total order on monomials where a>b => ac>bc for all
+  /// monomials a,b,c and where the order is a well order. Only the
+  /// well order property could currently fail. It is equivalent to
+  /// stating that x>1 for all variables x.
+  bool isMonomialOrder() const {
+    for (VarIndex var = 0; var < varCount(); ++var) {
+      // Check that x_var > 1.
+      for (size_t grading = 0; ; ++grading) {
+        if (grading == gradingCount) {
+          // The column was entirely zero, so x_var > 1 if and only if the
+          // base ordering is lex.
+          if (baseOrder() != LexBaseOrder)
+            return false;
+          break;
+        }
+        const auto index = grading * gradingCount() + var;
+        MATHICGB_ASSERT(index < mGradings.size());
+        const auto weight = mGradings[index];
+        if (weight != 0) {
+          // We have found the first non-zero weight in this column,
+          // so x_var > 1 if and only if this weight is positive.
+          if (weight < 0)
+            return false;
+          break;
+        }
+      }
+    }
+    return true;
   }
 
 private:
+  bool debugAssertValid() {
+#ifdef MATHICGB_DEBUG
+    MATHICGB_ASSERT(mGradings.size() == gradingCount() * varCount());
+    MATHICGB_ASSERT(
+      mComponentBefore == ComponentAfterBaseOrder ||
+      mComponentBefore <= gradingCount()
+    );
+    MATHICGB_ASSERT(
+      mBaseOrder == LexBaseOrder ||
+      mBaseOrder == RevLexBaseOrder
+    );
+    if (varCount() == 0) {
+      MATHICGB_ASSERT(mGradings.empty());
+      MATHICGB_ASSERT(baseOrder() == RevLexBaseOrder());
+      MATHICGB_ASSERT(mComponentBefore == ComponentAfterBaseOrder);
+    }
+#endif
+    return true;
+  }
+
   const VarIndex mVarCount;
-  std::vector<Weight> mGradings;
-  bool mTotalDegreeGrading;
-  BaseOrder mBaseOrder;
-  size_t mComponentBefore;
-  bool mUseSchreyerOrder;
-  bool mComponentsAscendingDesired;
+  const std::vector<Weight> mGradings;
+  const BaseOrder mBaseOrder;
+  const size_t mComponentBefore;
 };
 
 #endif

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