[mathicgb] 330/393: Added support for both left and right variants of lex and revlex to the library interface and in the engine. The file IO format does not support these new orders so far.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:30 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 1ca22f5c7a0afb0187ee70cf96f6574a360d585b
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Tue Aug 20 14:00:10 2013 +0200

    Added support for both left and right variants of lex and revlex to the library interface and in the engine. The file IO format does not support these new orders so far.
---
 src/mathicgb.cpp               |  73 ++++++++++++++++++++++------
 src/mathicgb.h                 |  34 +++++++++----
 src/mathicgb/MathicIO.cpp      |  11 +++--
 src/mathicgb/MonoMonoid.hpp    | 108 +++++++++++++++++++++++++++++++++--------
 src/mathicgb/MonoOrder.hpp     |  49 +++++++++++++------
 src/mathicgb/MonoProcessor.hpp |  21 ++++----
 src/mathicgb/PolyRing.cpp      |   4 +-
 src/mathicgb/PolyRing.hpp      |   4 +-
 src/test/MonoMonoid.cpp        |  83 +++++++++++++++++++++----------
 src/test/mathicgb.cpp          |   6 +--
 10 files changed, 289 insertions(+), 104 deletions(-)

diff --git a/src/mathicgb.cpp b/src/mathicgb.cpp
index 53001e0..406db27 100755
--- a/src/mathicgb.cpp
+++ b/src/mathicgb.cpp
@@ -336,7 +336,7 @@ struct GroebnerConfiguration::Pimpl {
   Pimpl(Coefficient modulus, VarIndex varCount):
     mModulus(modulus),
     mVarCount(varCount),
-    mBaseOrder(ReverseLexicographicBaseOrder),
+    mBaseOrder(RevLexDescendingBaseOrder),
     mGradings(varCount, 1),
     mComponentBefore(ComponentAfterBaseOrder),
     mComponentsAscending(true),
@@ -360,8 +360,10 @@ struct GroebnerConfiguration::Pimpl {
 
   static bool baseOrderValid(const BaseOrder order) {
     return
-      order == LexicographicBaseOrder ||
-      order == ReverseLexicographicBaseOrder;
+      order == RevLexDescendingBaseOrder ||
+      order == LexDescendingBaseOrder ||
+      order == RevLexAscendingBaseOrder ||
+      order == LexAscendingBaseOrder;
   }
 
   static bool reducerValid(const Reducer reducer) {
@@ -443,6 +445,21 @@ auto GroebnerConfiguration::varCount() const -> VarIndex {
   return mPimpl->mVarCount;
 }
 
+const char* GroebnerConfiguration::baseOrderName(BaseOrder order) {
+  switch (order) {
+    case RevLexDescendingBaseOrder:
+      return "reverse lexicographic descending";
+    case LexDescendingBaseOrder:
+      return "lexicographic descending";
+    case RevLexAscendingBaseOrder:
+      return "reverse lexicographic ascending";
+    case LexAscendingBaseOrder:
+      return "lexicographic ascending";
+    default:
+      return "(ERROR: invalid base order)";
+  }
+}
+
 bool GroebnerConfiguration::setMonomialOrderInternal(
   MonomialOrderData order
 ) {
@@ -462,7 +479,10 @@ bool GroebnerConfiguration::setMonomialOrderInternal(
         if (e > 0)
           goto orderGlobalForVar;
       }
-      if (order.baseOrder == ReverseLexicographicBaseOrder)
+      if (
+        order.baseOrder == RevLexAscendingBaseOrder ||
+        order.baseOrder == RevLexDescendingBaseOrder
+      )
         return false; // order not global
     orderGlobalForVar:;
     }
@@ -559,6 +579,27 @@ const char* GroebnerConfiguration::logging() const {
 }
 
 // ** Implementation of class GroebnerInputIdealStream
+namespace {
+  PolyRing::Monoid::Order::BaseOrder translateBaseOrder(
+    const GroebnerConfiguration::BaseOrder baseOrder
+  ) {
+    typedef PolyRing::Monoid::Order Internal;
+    typedef GroebnerConfiguration External;
+    switch (baseOrder) {
+    default:
+      MATHICGB_ASSERT(false);
+    case External:: RevLexDescendingBaseOrder:
+      return Internal::RevLexBaseOrderFromRight;
+    case External::LexDescendingBaseOrder:
+      return Internal::LexBaseOrderFromLeft;
+    case External::RevLexAscendingBaseOrder:
+      return Internal::RevLexBaseOrderFromLeft;
+    case External::LexAscendingBaseOrder:
+      return Internal::LexBaseOrderFromRight;
+    }
+  }
+}
+
 struct GroebnerInputIdealStream::Pimpl {
   Pimpl(const GroebnerConfiguration& conf):
     ring(
@@ -566,10 +607,7 @@ struct GroebnerInputIdealStream::Pimpl {
       PolyRing::Monoid::Order(
         conf.varCount(),
         std::move(conf.monomialOrder().second),
-        conf.monomialOrder().first ==
-          GroebnerConfiguration::LexicographicBaseOrder ?
-          PolyRing::Monoid::Order::LexBaseOrder :
-          PolyRing::Monoid::Order::RevLexBaseOrder,
+        translateBaseOrder(conf.monomialOrder().first),
         conf.componentBefore(),
         conf.componentsAscending(),
         conf.schreyering()
@@ -681,7 +719,7 @@ void GroebnerInputIdealStream::appendTermDone(Coefficient coefficient) {
 
   // @todo: do this directly into the polynomial instead of copying a second
   // time.
-  mPimpl->ring.monomialSetExponents(mPimpl->monomial, mExponents);
+  mPimpl->ring.monomialSetExternalExponents(mPimpl->monomial, mExponents);
   mPimpl->poly.appendTerm(coefficient, mPimpl->monomial);
 
   MATHICGB_ASSERT(debugAssertValid());
@@ -737,6 +775,7 @@ namespace mgbi {
 namespace mgbi {
   struct IdealAdapter::Pimpl {
     std::unique_ptr<Basis> basis;
+    std::unique_ptr<Exponent[]> tmpTerm;
   };
 
   IdealAdapter::IdealAdapter():
@@ -770,13 +809,17 @@ namespace mgbi {
   ) const -> std::pair<Coefficient, const Exponent*> {
     MATHICGB_ASSERT(mPimpl->basis.get() != 0);
     MATHICGB_ASSERT(poly < mPimpl->basis->size());
-    const auto& p = *mPimpl->basis->getPoly(poly);
 
+    const auto& monoid = mPimpl->basis->ring().monoid();
+    const auto& p = *mPimpl->basis->getPoly(poly);
     MATHICGB_ASSERT(term < p.nTerms());
-    return std::make_pair(
-      p.coefficientAt(term),
-      p.monomialAt(term).unsafeGetRepresentation() + 1
-    );
+    MATHICGB_ASSERT(p.ring().monoid() == monoid);
+
+    const auto& from = p.monomialAt(term);
+    auto to = mPimpl->tmpTerm.get();
+    for (VarIndex var = 0; var < monoid.varCount(); ++var)
+      to[var] = monoid.externalExponent(from, var);
+    return std::make_pair(p.coefficientAt(term), to);
   }
 }
 
@@ -870,6 +913,8 @@ namespace mgbi {
     typedef mgb::GroebnerConfiguration::Callback::Action Action;
     if (callback.lastAction() != Action::StopWithNoOutputAction) {
       PimplOf()(output).basis = alg.basis().toBasisAndRetireAll();
+      PimplOf()(output).tmpTerm =
+        make_unique_array<GConf::Exponent>(basis.ring().varCount());
       return true;
     } else
       return false;
diff --git a/src/mathicgb.h b/src/mathicgb.h
index 7483ee4..3f78ade 100755
--- a/src/mathicgb.h
+++ b/src/mathicgb.h
@@ -61,17 +61,31 @@ namespace mgb { // Part of the public interface of MathicGB
     VarIndex varCount() const;
 
     enum BaseOrder {
-      /// Lexicographic order where variables with higher
-      /// index are greater (x_1 > x_2 > ... > x_n). TODO: or is it the
-      /// other way around?
-      LexicographicBaseOrder = 0,
-
-      /// Reverse lexicographic order where variables with higher
-      /// index are greater (x_1 > x_2 > ... > x_n). TODO: or is it the
-      /// other way around?
-      ReverseLexicographicBaseOrder = 1
+      /// Reverse lexicographic order with x_1 > x_2 > ... > x_n.
+      /// Can be described as rev-lex-descending or rev-lex-from-right.
+      /// This is what people usually mean when they say rev-lex.
+      RevLexDescendingBaseOrder = 0,
+
+      /// Lexicographic order with x_1 > x_2 > ... > x_n.
+      /// Can be described as lex-descending or lex-from-left.
+      /// This is what people usually mean when they say lex.
+      LexDescendingBaseOrder = 1,
+
+      /// Reverse lexicographic order with x_1 < x_2 < ... < x_n.
+      /// Can be described as rev-lex-ascending or rev-lex-from-left.
+      RevLexAscendingBaseOrder = 2,
+
+      /// Lexicographic order with x_1 < x_2 < ... < x_n.
+      /// Can be described as lex-ascending or lex-from-right.
+      LexAscendingBaseOrder = 3
     };
 
+    /// Returns a name for the passed in base order.
+    /// Ownership of the string is not passed on. You should not depend on
+    /// the string having any particular value, except that it is something
+    /// that will identify the order to a human.
+    static const char* baseOrderName(BaseOrder order);
+
     /// Specifies the monomial order to compute a Groebner basis with
     /// respect to. You must ensure that the order that you are specifying
     /// is in fact a monomial order.
@@ -774,6 +788,8 @@ namespace mgb {
       VarIndex varCount() const;
       size_t polyCount() const;
       size_t termCount(PolyIndex poly) const;
+
+      // Return value only valid until the next call to term.
       ConstTerm term(PolyIndex poly, TermIndex term) const;
 
     private:
diff --git a/src/mathicgb/MathicIO.cpp b/src/mathicgb/MathicIO.cpp
index ecd51fd..26d01fa 100755
--- a/src/mathicgb/MathicIO.cpp
+++ b/src/mathicgb/MathicIO.cpp
@@ -25,7 +25,11 @@ auto MathicIO::readRing(
   auto ring = make_unique<PolyRing>
     (std::move(baseField), Monoid(std::move(order)));
 
-  Processor processor(ring->monoid(), componentsAscendingDesired, schreyering);
+  Processor processor(
+    ring->monoid(),
+    componentsAscendingDesired,
+    schreyering
+  );
 
   return std::make_pair(std::move(ring), std::move(processor));
 }
@@ -92,7 +96,8 @@ auto MathicIO::readOrder(
   Order order(
     varCount,
     std::move(gradings),
-    lexBaseOrder ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+    lexBaseOrder ?
+      Order::LexBaseOrderFromRight : Order::RevLexBaseOrderFromRight,
     componentCompareIndex,
     componentsAscendingDesired,
     schreyering
@@ -108,7 +113,7 @@ void MathicIO::writeOrder(
   MATHICGB_ASSERT(Monoid::HasComponent || !withComponent);
 
   const auto baseOrder =
-    order.baseOrder() == Order::LexBaseOrder ? "lex" : "revlex";
+    order.baseOrder() == Order::LexBaseOrderFromRight ? "lex" : "revlex";
   const auto componentOrder =
     order.componentsAscendingDesired() ? "component" : "revcomponent";
 
diff --git a/src/mathicgb/MonoMonoid.hpp b/src/mathicgb/MonoMonoid.hpp
index c6c6e5e..54ebbf4 100755
--- a/src/mathicgb/MonoMonoid.hpp
+++ b/src/mathicgb/MonoMonoid.hpp
@@ -53,15 +53,15 @@ namespace MonoMonoidInternal {
       mEntryCount(std::max<VarIndex>(mOrderIndexEnd + StoreHash, 1)),
       mHashCoefficients(makeHashCoefficients(order.varCount())),
       mOrderIsTotalDegreeRevLex
-        (order.baseOrder() == Order::RevLexBaseOrder && order.isTotalDegree()),
-      mLexBaseOrder(order.baseOrder() == Order::LexBaseOrder),
+        (!order.hasLexBaseOrder() && order.isTotalDegree()),
+      mLexBaseOrder(order.hasLexBaseOrder()),
       mGradings(makeGradings(order)),
       mComponentGradingIndex(
         reverseComponentGradingIndex
           (order.gradingCount(), order.componentGradingIndex())
-      )
-    {
-    }
+      ),
+      mVarsReversed(order.hasFromLeftBaseOrder())
+    {}
 
     VarIndex varCount() const {return mVarCount;}
     VarIndex gradingCount() const {return mGradingCount;}
@@ -71,6 +71,7 @@ namespace MonoMonoidInternal {
     VarIndex orderIndexBegin() const {return mOrderIndexBegin;}
     VarIndex hashIndex() const {return mOrderIndexEnd;}
     VarIndex componentGradingIndex() const {return mComponentGradingIndex;}
+    bool varsReversed() const {return mVarsReversed;}
 
   protected:
     typedef std::vector<Exponent> HashCoefficients;
@@ -79,7 +80,9 @@ namespace MonoMonoidInternal {
     static Gradings makeGradings(const Order& order) {
       auto gradings = order.gradings();
       reverseGradings(order.varCount(), gradings);
-      if (order.baseOrder() == Order::RevLexBaseOrder)
+      if (order.hasFromLeftBaseOrder())
+        reverseVarsInGradings(order.varCount(), gradings);
+      if (!order.hasLexBaseOrder())
         negateGradings(gradings);
       return gradings;
     }
@@ -110,6 +113,22 @@ namespace MonoMonoidInternal {
         gradings[i] = -gradings[i];
     }
 
+    /// Replace each row (e_0, e_1, ..., e_n) with (e_n, ..., e_1, e_0).
+    static void reverseVarsInGradings(
+      const size_t varCount,
+      Gradings& gradings
+    ) {
+      if (varCount == 0)
+        return;
+      MATHICGB_ASSERT(gradings.size() % varCount == 0);
+      auto rowBegin = gradings.begin();
+      while (rowBegin != gradings.end()) {
+        const auto rowEnd = rowBegin + varCount;
+        std::reverse(rowBegin, rowEnd);
+        rowBegin = rowEnd;
+      }
+    }
+
     /// Since comparisons go opposite direction, we need to reverse
     /// the component grading index, unless it's the special value
     /// indicating that it goes last.
@@ -196,7 +215,7 @@ namespace MonoMonoidInternal {
     /// used. This applies as well to degrees, which implies that
     /// degrees have to be stored negated if doing revlex.
     const bool mLexBaseOrder;
-    
+
     /// Defines a matrix where each row is a grading. The degree of a
     /// monomial with respect to grading g is the dot product of the
     /// exponent vector of that monomial with row g of the matrix
@@ -204,7 +223,15 @@ namespace MonoMonoidInternal {
     /// mOrderIsTotalDegreeRevLex is true then mGradings is empty but
     /// implicitly it is a single grading consisting of all 1s and the
     /// base order is revlex.
-    std::vector<Exponent> mGradings;    
+    std::vector<Exponent> mGradings;
+
+    /// All base comparison considers exponents starting from the right,
+    /// yet we need to support base orders starting from the left. This
+    /// is achieved by reversing the order of the variables. The value
+    /// of this variable indicates whether this has happened, in which
+    /// case it needs to be done again before showing a monomial to the
+    /// outside world.
+    const bool mVarsReversed;
   };
 }
 
@@ -353,7 +380,8 @@ public:
     return Order(
       varCount(),
       std::move(orderGradings),
-      isLexBaseOrder() ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+      isLexBaseOrder() ?
+        Order::LexBaseOrderFromRight : Order::RevLexBaseOrderFromRight,
       Base::reverseComponentGradingIndex
         (gradingCount(), componentGradingIndex()),
       componentsAscendingDesired,
@@ -378,7 +406,11 @@ public:
   /// Returns the number of variables. This is also the number of
   /// exponents in the exponent vector of a monomial.
   using Base::varCount;
-  //VarIndex varCount() const {return mVarCount;}
+
+  /// Returns true if the variables in this ring have been reversed
+  /// so that the first one becomes the last one and so on. Use
+  /// MonoProcessor to reverse monomials for input and output.
+  using Base::varsReversed;
 
 
   // *** Monomial accessors and queries
@@ -393,11 +425,39 @@ public:
     return ptr(mono, exponentsIndexEnd());
   }
 
+  /// The indices of variables might be permuted in this monoid in order to
+  /// implement certain monomial orders in a fast way. This method returns
+  /// the unpermuted index that gets permuted to var. Knowing this mapping
+  /// is necessary when importing monomials from and when exporting monomials
+  /// to a party that does not use this scheme. For example when writing a
+  /// monomial to a file in a format that is intended to be readable by
+  /// other programs or by a human.
+  VarIndex externalVar(const VarIndex var) const {
+    // At the moment, this method happens to be its own inverse. Do not depend
+    // on that.
+    MATHICGB_ASSERT(var < varCount());
+    const auto eVar = varsReversed() ? varCount() - 1 - var : var;
+    MATHICGB_ASSERT(eVar < varCount());
+    return eVar;
+  }
+
+  /// The inverse mapping of externalVar().
+  VarIndex internalVar(const VarIndex var) const {
+    // Do not depend on knowing that this is the implementation.
+    return externalVar(var);
+  }
+
   /// Returns the exponent of var in mono.
   Exponent exponent(ConstMonoRef mono, const VarIndex var) const {
     MATHICGB_ASSERT(var < varCount());
     return access(mono, exponentsIndexBegin() + var);
-  } 
+  }
+
+  // The exponent of var as it would be if variables were not permuted.
+  Exponent externalExponent(ConstMonoRef mono, const VarIndex var) const {
+    MATHICGB_ASSERT(var < varCount());
+    return exponent(mono, externalVar(var));
+  }
 
   /// Returns the component of the monomial. Monomials not from a
   /// module have component zero. In a module mono*e_i has component
@@ -806,6 +866,7 @@ public:
     MATHICGB_ASSERT(HasComponent == MonoidFrom::HasComponent);
     MATHICGB_ASSERT(monoidFrom.debugValid(from));
     MATHICGB_ASSERT(monoidFrom.varCount() == varCount());
+    MATHICGB_ASSERT(monoidFrom.varsReversed() == varsReversed());
     MATHICGB_ASSERT
       ((std::is_same<Exponent, typename MonoidFrom::Exponent>::value));
 
@@ -844,14 +905,19 @@ public:
     MATHICGB_ASSERT(debugValid(mono));
   }
 
-  /// Sets all the exponents of mono. exponents must point to an array
-  /// of size varCount().
-  void setExponents(const Exponent* exponents, MonoRef mono) const {
+  /// Sets all the exponents of mono from an external/unpermuted array.
+  /// exponents must point to an array of size varCount().
+  /// After this, exponent(mono, var) is exponents[externalVar(var)].
+  /// The value of exponents[var] becomes the exponent of internalVar(var).
+  void setExternalExponents(const Exponent* exponents, MonoRef mono) const {
     MATHICGB_ASSERT(exponents != 0);
 
     if (HasComponent)
       access(mono, componentIndex()) = 0;
-    std::copy_n(exponents, varCount(), ptr(mono, exponentsIndexBegin()));
+    for (VarIndex iVar = 0; iVar < varCount(); ++iVar) {
+      const auto eVar = externalVar(iVar);
+      access(mono, exponentsIndexBegin() + iVar) = exponents[eVar];
+    }
     setOrderData(mono);
     setHash(mono);
 
@@ -1867,7 +1933,8 @@ auto MonoMonoid<E, HC, SH, SO>::readMonoid(std::istream& in) ->
   Order order(
     varCount,
     std::move(gradings),
-    lexBaseOrder ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+    lexBaseOrder ?
+      Order::LexBaseOrderFromRight : Order::RevLexBaseOrderFromRight,
     componentCompareIndex
   );
   return std::make_pair(
@@ -1941,7 +2008,7 @@ void MonoMonoid<E, HC, SH, SO>::parseM2(std::istream& in, MonoRef mono) const {
     }
 
     in.get();
-    auto& exponent = access(mono, exponentsIndexBegin() + var);
+    auto& exponent = access(mono, exponentsIndexBegin() + externalVar(var));
     if (isdigit(in.peek())) {
       typename unchar<Exponent>::type e;
       in >> e;
@@ -1987,7 +2054,8 @@ void MonoMonoid<E, HC, SH, SO>::printM2(
 
   bool printedSome = false;
   for (VarIndex var = 0; var < varCount(); ++var) {
-    if (exponent(mono, var) == 0)
+    const Exponent& e = externalExponent(mono, var);
+    if (e == 0)
       continue;
     char letter;
     if (var < letterCount)
@@ -2000,8 +2068,8 @@ void MonoMonoid<E, HC, SH, SO>::printM2(
     }
     printedSome = true;
     out << letter;
-    if (exponent(mono, var) != 1)
-      out << static_cast<typename unchar<Exponent>::type>(exponent(mono, var));
+    if (e != 1)
+      out << static_cast<typename unchar<Exponent>::type>(e);
   }
   if (!printedSome)
     out << '1';
diff --git a/src/mathicgb/MonoOrder.hpp b/src/mathicgb/MonoOrder.hpp
index 6877a2a..699a397 100755
--- a/src/mathicgb/MonoOrder.hpp
+++ b/src/mathicgb/MonoOrder.hpp
@@ -10,11 +10,9 @@ MATHICGB_NAMESPACE_BEGIN
 
 /// Class used to describe an monomial order and/or a module monomial
 /// order. Use this class to construct a monoid. The monoid does the
-/// actual comparisons.
-///
-/// You can extend the functionality for ordering offered here for
-/// module mononials by pre- and post-processing of monomials. See
-/// MonoProcessor.
+/// actual comparisons. Monomials must be preprocessed by MonoProcessor -
+/// otherwise the ordering may not be correct. MonoProcessor also offers
+/// additional parameters for making orders.
 template<class Weight>
 class MonoOrder;
 
@@ -28,18 +26,24 @@ public:
   static const size_t ComponentAfterBaseOrder = static_cast<size_t>(-1);
 
   enum BaseOrder {
-    /// Lexicographic order with x0 < x1 < ... < x_n.
-    LexBaseOrder = 0,
+    /// Lexicographic order with x_0 < x_1 < ... < x_n.
+    LexBaseOrderFromRight = 0,
 
-    /// Reverse lexicographic order with x0 > x1 > ... > x_n.
-    RevLexBaseOrder = 1
+    /// Reverse lexicographic order with x_0 > x_1 > ... > x_n.
+    RevLexBaseOrderFromRight = 1,
+
+    /// Lexicographic order with x_0 > x_1 > ... > x_n.
+    LexBaseOrderFromLeft = 2,
+
+    /// Reverse lexicographic order with x_0 < x_1 < ... < x_n.
+    RevLexBaseOrderFromLeft = 3
   };
 
   /// 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 BaseOrder baseOrder = RevLexBaseOrderFromRight,
     const size_t componentBefore = ComponentAfterBaseOrder,
     const bool componentsAscendingDesired = true,
     const bool schreyering = true
@@ -88,7 +92,7 @@ public:
   MonoOrder(
     const VarIndex varCount,
     Gradings&& gradings,
-    const BaseOrder baseOrder = RevLexBaseOrder,
+    const BaseOrder baseOrder = RevLexBaseOrderFromRight,
     const size_t componentBefore = ComponentAfterBaseOrder,
     const bool componentsAscendingDesired = true,
     const bool schreyering = true
@@ -101,6 +105,7 @@ public:
     mSchreyering(schreyering)
   {
 #ifdef MATHCGB_DEBUG
+    // todo: fix this, it isn't checking the right row of the matrix
     if (componentBefore != ComponentAfterBaseOrder) {
       for (VarIndex var = 0; var < varCount(); ++var) {
         MATHICGB_ASSERT(mGradings[var] == 0);
@@ -133,6 +138,18 @@ public:
 
   BaseOrder baseOrder() const {return mBaseOrder;}
 
+  bool hasFromLeftBaseOrder() const {
+    return
+      baseOrder() == LexBaseOrderFromLeft ||
+      baseOrder() == RevLexBaseOrderFromLeft;
+  }
+
+  bool hasLexBaseOrder() const {
+    return
+      baseOrder() == LexBaseOrderFromLeft ||
+      baseOrder() == LexBaseOrderFromRight;
+  }
+
   /// 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
@@ -145,7 +162,7 @@ public:
         if (grading == gradingCount) {
           // The column was entirely zero, so x_var > 1 if and only if the
           // base ordering is lex.
-          if (baseOrder() != LexBaseOrder)
+          if (!hasLexBaseOrder())
             return false;
           break;
         }
@@ -191,12 +208,14 @@ private:
       mComponentGradingIndex < gradingCount()
     );
     MATHICGB_ASSERT(
-      mBaseOrder == LexBaseOrder ||
-      mBaseOrder == RevLexBaseOrder
+      mBaseOrder == LexBaseOrderFromLeft ||
+      mBaseOrder == RevLexBaseOrderFromLeft ||
+      mBaseOrder == LexBaseOrderFromRight ||
+      mBaseOrder == RevLexBaseOrderFromRight 
     );
     if (varCount() == 0) {
       MATHICGB_ASSERT(mGradings.empty());
-      MATHICGB_ASSERT(baseOrder() == RevLexBaseOrder());
+      MATHICGB_ASSERT(baseOrder() == RevLexBaseOrderFromRight());
       MATHICGB_ASSERT(mComponentGradingIndex == ComponentAfterBaseOrder);
     }
 #endif
diff --git a/src/mathicgb/MonoProcessor.hpp b/src/mathicgb/MonoProcessor.hpp
index adb5f76..c973a1f 100755
--- a/src/mathicgb/MonoProcessor.hpp
+++ b/src/mathicgb/MonoProcessor.hpp
@@ -8,11 +8,10 @@
 MATHICGB_NAMESPACE_BEGIN
 
 /// 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.
+/// orders not directly supported by the monoid.
 ///
-/// todo: distinguish monomials from module monomials using two
-/// different monoids.
+/// @todo: distinguish monomials from module monomials, perhaps with
+/// two separate classes.
 template<class Monoid>
 class MonoProcessor;
 
@@ -21,11 +20,11 @@ class MonoProcessor {
 public:
   typedef M Monoid;
   typedef typename Monoid::VarIndex VarIndex;
+  typedef typename Monoid::Component Component;
   typedef typename Monoid::MonoVector MonoVector;
   typedef typename Monoid::MonoRef MonoRef;
   typedef typename Monoid::ConstMonoRef ConstMonoRef;
   typedef typename Monoid::ConstMonoPtr ConstMonoPtr;
-  typedef typename Monoid::Component Component;
 
   MonoProcessor(
     const Monoid& monoid,
@@ -38,6 +37,11 @@ public:
     mSchreyerMultipliersMemory(monoid)
   {}
 
+  void setComponentsAscendingDesired(bool value) {
+    mComponentsAscendingDesired = value;
+  }
+  bool componentsAscendingDesired() const {return mComponentsAscendingDesired;}
+
   void setSchreyering(bool value) {mSchreyering = true;}
   bool schreyering() const {return mSchreyering;}
 
@@ -69,7 +73,6 @@ public:
       mSchreyerMultipliers.emplace_back((*it).ptr());
     }
   }
-    
 
   void preprocess(MonoRef mono) const {
     if (hasSchreyerMultipliers())
@@ -96,11 +99,6 @@ public:
       componentsAscendingDesired() != monoid().componentsAscending();
   }
 
-  void setComponentsAscendingDesired(bool value) {
-    mComponentsAscendingDesired = value;
-  }
-  bool componentsAscendingDesired() const {return mComponentsAscendingDesired;}
-
   bool hasSchreyerMultipliers() const {
     return !mSchreyerMultipliers.empty();
   }
@@ -126,6 +124,7 @@ private:
     return *mSchreyerMultipliers[component];
   }
 
+  bool mOrderFromLeft;
   bool mComponentsAscendingDesired;
   Component mComponentCount;
   bool mSchreyering;
diff --git a/src/mathicgb/PolyRing.cpp b/src/mathicgb/PolyRing.cpp
index fe742a0..66c063e 100755
--- a/src/mathicgb/PolyRing.cpp
+++ b/src/mathicgb/PolyRing.cpp
@@ -30,8 +30,8 @@ PolyRing::PolyRing(
       nvars,
       std::move(weights),
       lexBaseOrder ?
-        MonoOrder<exponent>::LexBaseOrder :
-        MonoOrder<exponent>::RevLexBaseOrder
+        MonoOrder<exponent>::LexBaseOrderFromRight :
+        MonoOrder<exponent>::RevLexBaseOrderFromRight
     )
   )
 {}
diff --git a/src/mathicgb/PolyRing.hpp b/src/mathicgb/PolyRing.hpp
index dde7d17..3e20175 100755
--- a/src/mathicgb/PolyRing.hpp
+++ b/src/mathicgb/PolyRing.hpp
@@ -328,8 +328,8 @@ public:
     monoid().setExponent(var, c, m);
   }
 
-  void monomialSetExponents(Monomial m, exponent* exponents) const {
-    monoid().setExponents(exponents, m);
+  void monomialSetExternalExponents(Monomial m, exponent* exponents) const {
+    monoid().setExternalExponents(exponents, m);
   }
 
   exponent monomialExponent(ConstMonomial m, size_t var) const {
diff --git a/src/test/MonoMonoid.cpp b/src/test/MonoMonoid.cpp
index d6fbde6..f19c918 100755
--- a/src/test/MonoMonoid.cpp
+++ b/src/test/MonoMonoid.cpp
@@ -587,7 +587,10 @@ TYPED_TEST(Monoid, Order) {
   typedef typename Monoid::Order Order;
   typedef typename Monoid::Exponent Exponent;
 
-  auto check = [](const Monoid& m, const char* sorted) -> void {
+  auto check = [](
+    const Monoid& m,
+    const char* const sorted
+  ) -> void {
     auto v = parseVector(m, sorted);
     for (auto greater = v.begin(); greater != v.end(); ++greater) {
       ASSERT_EQ(m.compare(*greater, *greater), Monoid::EqualTo);
@@ -610,11 +613,17 @@ TYPED_TEST(Monoid, Order) {
     "1 Z A z c b a c2 bc ac b2 ab a2 c3 abc b3 a3";
   check(Monoid(52), sortedTotalDegreeRevLex);
   check(
-    Monoid(Order(52, std::vector<Exponent>(52, 1), Order::RevLexBaseOrder)),
+    Monoid(
+      Order(52, std::vector<Exponent>(52, 1),
+      Order::RevLexBaseOrderFromRight)
+    ),
     sortedTotalDegreeRevLex
   );
   check(
-    Monoid(Order(52, std::vector<Exponent>(52, 7), Order::RevLexBaseOrder)),
+    Monoid(
+      Order(52, std::vector<Exponent>(52, 7),
+      Order::RevLexBaseOrderFromRight)
+    ),
     sortedTotalDegreeRevLex
   );
   std::vector<Exponent> revLexGradings(52, 1);
@@ -623,12 +632,16 @@ TYPED_TEST(Monoid, Order) {
       revLexGradings.push_back(var == grading ? -1 : 0);
   check(
     Monoid(
-      Order(52, std::vector<Exponent>(revLexGradings), Order::RevLexBaseOrder)
+      Order(52, std::vector<Exponent>(revLexGradings),
+      Order::RevLexBaseOrderFromRight)
     ),
     sortedTotalDegreeRevLex
   );
   check(
-    Monoid(Order(52, std::move(revLexGradings), Order::LexBaseOrder)),
+    Monoid(
+      Order(52, std::move(revLexGradings),
+      Order::LexBaseOrderFromRight)
+    ),
     sortedTotalDegreeRevLex
   );
 
@@ -656,7 +669,7 @@ TYPED_TEST(Monoid, Order) {
   // ab3: 11 21
   const auto sortedDupGradingsRevLex = "1 b c a bc c2 b3 bc3 ab3";
   check(
-    Monoid(Order(3, std::move(dupGradings), Order::RevLexBaseOrder)),
+    Monoid(Order(3, std::move(dupGradings), Order::RevLexBaseOrderFromRight)),
     sortedDupGradingsRevLex
   );
 
@@ -667,20 +680,30 @@ TYPED_TEST(Monoid, Order) {
   };
   std::vector<Exponent> lexGradings(
     lexGradingsArray,
-    lexGradingsArray + sizeof(lexGradingsArray)/sizeof(*lexGradingsArray)
+    lexGradingsArray + sizeof(lexGradingsArray) / sizeof(*lexGradingsArray)
   );
-  const auto sortedLex =
+  const auto sortedLexFromRight =
     "1 a a2 a3 b ab a2b b2 ab2 b3 c ac bc abc c2 ac2 bc2 c3";
+  auto lexGradingsCheck = [&](typename Order::BaseOrder baseOrder) {
+    check(
+      Monoid(Order(3, std::vector<Exponent>(lexGradings), baseOrder)),
+      sortedLexFromRight
+    );
+  };
+  lexGradingsCheck(Order::LexBaseOrderFromRight);
+  lexGradingsCheck(Order::RevLexBaseOrderFromRight);
+  lexGradingsCheck(Order::LexBaseOrderFromLeft);
+  lexGradingsCheck(Order::RevLexBaseOrderFromLeft);
   check(
-    Monoid(
-      Order(3, std::vector<Exponent>(lexGradings), Order::RevLexBaseOrder)
-    ),
-    sortedLex
+    Monoid(Order(3, std::vector<Exponent>(), Order::LexBaseOrderFromRight)),
+    sortedLexFromRight
+  );
+  const auto sortedLexFromLeft =
+    "1 c c2 c3 b cb bc2 b2 b2c b3 a ac ab abc a2 a2c a2b a3";
+  check(
+    Monoid(Order(3, std::vector<Exponent>(), Order::LexBaseOrderFromLeft)),
+    sortedLexFromLeft
   );
-  check
-    (Monoid(Order(3, std::move(lexGradings), Order::LexBaseOrder)), sortedLex);
-  check
-    (Monoid(Order(3, std::vector<Exponent>(), Order::LexBaseOrder)), sortedLex);
 }
 
 TYPED_TEST(Monoid, RelativelyPrime) {
@@ -706,12 +729,16 @@ TYPED_TEST(Monoid, RelativelyPrime) {
 
 TYPED_TEST(Monoid, SetExponents) {
   typedef TypeParam Monoid;
+  typedef typename Monoid::VarIndex VarIndex;
+  typedef typename Monoid::MonoVector MonoVector;
   Monoid m(5);
-  auto v = parseVector(m, "a1b2c3d4e5");
-  typename Monoid::Exponent exponents[] = {1, 2, 3, 4, 5};
+  MonoVector v(m);
   v.push_back();
-  m.setExponents(exponents, v.back());
-  ASSERT_TRUE(m.equal(v.front(), v.back()));  
+  typename Monoid::Exponent exponents[] = {1, 2, 3, 4, 5};
+  m.setExternalExponents(exponents, v.back());
+  for (VarIndex var = 0; var < m.varCount(); ++var) {
+    ASSERT_EQ(exponents[var], m.externalExponent(v.back(), var));
+  }
 }
 
 TYPED_TEST(Monoid, HasAmpleCapacityTotalDegree) {
@@ -725,12 +752,14 @@ TYPED_TEST(Monoid, HasAmpleCapacityTotalDegree) {
     
     std::vector<Exponent> ones(varCount, 1);
     Monoid monoidTotalDegreeImplicit
-      (Order(varCount, std::move(ones), Order::RevLexBaseOrder));
+      (Order(varCount, std::move(ones), Order::RevLexBaseOrderFromRight));
 
     std::vector<Exponent> mostlyOnes(varCount, 1);
     mostlyOnes[0] = 7;
-    Monoid monoidGeneral
-      (Order(varCount, std::move(mostlyOnes), Order::RevLexBaseOrder));
+    Monoid monoidGeneral(
+      Order(varCount, std::move(mostlyOnes),
+      Order::RevLexBaseOrderFromRight)
+    );
 
     Monoid* monoids[] = {
       &monoidTotalDegree,
@@ -784,8 +813,11 @@ TYPED_TEST(Monoid, CopyEqualConversion) {
   typedef MonoMonoid<Exponent, HasComponent, false, false> MonoidNone;
   typedef MonoMonoid<Exponent, HasComponent, true, true> MonoidAll;
   for (VarIndex varCount = 1; varCount < 33; ++varCount) {
-    const Order order
-      (varCount, std::vector<Exponent>(varCount, 1), Order::RevLexBaseOrder);
+    const Order order(
+      varCount,
+      std::vector<Exponent>(varCount, 1),
+      Order::RevLexBaseOrderFromRight
+    );
     MonoidNone none(order);
     Monoid some(Monoid::create(none));
     MonoidAll all(MonoidAll::create(some));
@@ -875,3 +907,4 @@ TYPED_TEST(Monoid, CopyEqualConversion) {
     ASSERT_TRUE(some.equal(some2, some3));
   }
 }
+
diff --git a/src/test/mathicgb.cpp b/src/test/mathicgb.cpp
index bad52fd..9a811ef 100755
--- a/src/test/mathicgb.cpp
+++ b/src/test/mathicgb.cpp
@@ -533,7 +533,7 @@ TEST(MathicGBLib, SimpleEliminationGB) {
       mgb::GroebnerConfiguration::MatrixReducer;
     configuration.setReducer(reducer);
     configuration.setMonomialOrder(
-      mgb::GroebnerConfiguration::BaseOrder::ReverseLexicographicBaseOrder, 
+      mgb::GroebnerConfiguration::BaseOrder::RevLexDescendingBaseOrder, 
       gradings
     );
 
@@ -565,9 +565,9 @@ TEST(MathicGBLib, SimpleEliminationGB) {
 TEST(MathicGBLib, GlobalOrderOrNot) {
   mgb::GroebnerConfiguration conf(101, 4);
   const auto lex =
-    mgb::GroebnerConfiguration::BaseOrder::LexicographicBaseOrder;
+    mgb::GroebnerConfiguration::BaseOrder::LexAscendingBaseOrder;
   const auto revLex =
-    mgb::GroebnerConfiguration::BaseOrder::ReverseLexicographicBaseOrder;
+    mgb::GroebnerConfiguration::BaseOrder::RevLexDescendingBaseOrder;
 
   typedef mgb::GroebnerConfiguration::Exponent Exponent;
   std::vector<Exponent> mat;

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