[mathicgb] 213/393: Added full support for comparison to MonoMonoid, along with module monomial and non-total-degree grading. Also forwarded compare from PolyRing to MonoMonoid.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:03 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 69ba192ca779c858c1742e50667e6b49a13d1a2a
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Sat Mar 30 20:46:40 2013 +0100

    Added full support for comparison to MonoMonoid, along with module monomial and non-total-degree grading. Also forwarded compare from PolyRing to MonoMonoid.
---
 build/setup/make-Makefile.sh   | 30 +++++++++++---
 src/mathicgb/MonoMonoid.hpp    | 94 ++++++++++++++++++++++++++++++++++++------
 src/mathicgb/PolyRing.cpp      | 59 +++++++++++++++++++++-----
 src/mathicgb/PolyRing.hpp      | 48 ++++++++++++++++-----
 src/test/MonoMonoid.cpp        |  2 +-
 src/test/QuadMatrixBuilder.cpp |  2 +-
 6 files changed, 196 insertions(+), 39 deletions(-)

diff --git a/build/setup/make-Makefile.sh b/build/setup/make-Makefile.sh
index b475471..f572a44 100755
--- a/build/setup/make-Makefile.sh
+++ b/build/setup/make-Makefile.sh
@@ -38,6 +38,16 @@ targetsLDFLAGS+=("");
 targetsMakeArgs+=("");
 targetsDefault+=("yes");
 
+# new release
+relnIndex=${#targetsName[@]};
+targetsName+=("reln");
+targetsDescription+=("New release build. Optimized, no debug symbols, no asserts.");
+targetsCPPFLAGS+=("-O2 -DMATHICGB_USE_MONOID");
+targetsCXXFLAGS+=("");
+targetsLDFLAGS+=("");
+targetsMakeArgs+=("");
+targetsDefault+=("no");
+
 # optimized with asserts
 relassIndex=${#targetsName[@]};
 targetsName+=("relass");
@@ -48,11 +58,21 @@ targetsLDFLAGS+=("");
 targetsMakeArgs+=("");
 targetsDefault+=("yes");
 
-# debug with asserts
-debIndex=${#targetsName[@]};
-targetsName+=("deb");
-targetsDescription+=("Debug build with asserts. Not optimized.");
-targetsCPPFLAGS+=("-g -DMEMTAILOR_DEBUG -DMATHIC_DEBUG -DMATHICGB_DEBUG $mildWarn");
+# optimized with asserts
+relassnIndex=${#targetsName[@]};
+targetsName+=("relassn");
+targetsDescription+=("Optimized build with asserts. No debug symbols.");
+targetsCPPFLAGS+=("-DMATHICGB_USE_MONOID -O2 -DMEMTAILOR_DEBUG -DMATHIC_DEBUG -DMATHICGB_DEBUG $mildWarn");
+targetsCXXFLAGS+=("");
+targetsLDFLAGS+=("");
+targetsMakeArgs+=("");
+targetsDefault+=("no");
+
+# optimized with asserts
+relassIndex=${#targetsName[@]};
+targetsName+=("relass");
+targetsDescription+=("Optimized build with asserts. No debug symbols.");
+targetsCPPFLAGS+=("-O2 -DMEMTAILOR_DEBUG -DMATHIC_DEBUG -DMATHICGB_DEBUG $mildWarn");
 targetsCXXFLAGS+=("");
 targetsLDFLAGS+=("");
 targetsMakeArgs+=("");
diff --git a/src/mathicgb/MonoMonoid.hpp b/src/mathicgb/MonoMonoid.hpp
index 247f50b..9e468ec 100755
--- a/src/mathicgb/MonoMonoid.hpp
+++ b/src/mathicgb/MonoMonoid.hpp
@@ -87,15 +87,54 @@ public:
     GreaterThan = 1
   };
 
+  // *** Temporary compatibility code for migrating off PolyRing
+  friend class PolyRing;
+  static MonoRef toRef(Exponent* e) {return MonoRef(e);}
+  static ConstMonoRef toRef(const Exponent* e) {return ConstMonoRef(e);}
+
+  
 
   // *** Constructors and accessors
 
+  MonoMonoid(const std::vector<Exponent>& grading):
+    mVarCount(grading.size()),
+    mOrderEntryCount(1),
+    mOrderIndexBegin(1 + mVarCount),
+    mOrderIndexEnd(2 + mVarCount),
+    mHashCoefficients(mVarCount),
+    mGradingIsTotalDegree(
+      [&]() {
+        for (auto it = grading.begin(); it != grading.end(); ++it)
+          if (*it != 1)
+            return false;
+        return true;
+      }()
+    ),
+    mGrading(mGradingIsTotalDegree ? std::vector<Exponent>() : grading)
+  {
+    if (!mGradingIsTotalDegree) {
+      // Take negative values since reverse lex makes bigger values
+      // give smaller monomials, but we need bigger degrees to give
+      // bigger monomials.
+      mGrading.resize(varCount());
+      for (VarIndex var = 0; var < varCount(); ++var)
+        mGrading[var] = -grading[var];
+    }
+
+    std::srand(0); // To use the same hash coefficients every time.
+    for (VarIndex var = 0; var < varCount(); ++var)
+      mHashCoefficients[var] = static_cast<HashValue>(std::rand());      
+  }
+
+
   MonoMonoid(const VarIndex varCount):
     mVarCount(varCount),
     mOrderEntryCount(1),
-    mOrderIndexBegin(1 + varCount),
-    mOrderIndexEnd(2 + varCount),
-    mHashCoefficients(varCount)
+    mOrderIndexBegin(1 + mVarCount),
+    mOrderIndexEnd(2 + mVarCount),
+    mHashCoefficients(mVarCount),
+    mGradingIsTotalDegree(true),
+    mGrading()
   {
     std::srand(0); // To use the same hash coefficients every time.
     for (VarIndex var = 0; var < varCount; ++var)
@@ -180,7 +219,7 @@ public:
     MATHICGB_ASSERT(debugOrderValid(a));
     MATHICGB_ASSERT(debugOrderValid(b));
 
-    const auto stop = exponentsIndexBegin() - 1;
+    const auto stop = componentIndex() - 1;
     for (auto i = orderIndexEnd() - 1; i != stop; --i) {
       const auto cmp = access(a, i) - access(b, i);
       if (cmp < 0) return GreaterThan;
@@ -240,7 +279,7 @@ public:
     MATHICGB_ASSERT(debugValid(a));
     MATHICGB_ASSERT(debugValid(b));
 
-    for (auto i = 0; i < entryCount(); ++i)
+    for (auto i = lastEntryIndex(); i != beforeFirstIndex(); --i)
       access(prod, i) = access(a, i) + access(b, i);
 
     MATHICGB_ASSERT(debugValid(prod));
@@ -771,15 +810,20 @@ private:
     MATHICGB_ASSERT(orderIndexEnd() < entryCount());
     MATHICGB_ASSERT(orderEntryCount() == 1);
 
+    if (mGradingIsTotalDegree)
+      MATHICGB_ASSERT(mGrading.empty());
+    else
+      MATHICGB_ASSERT(mGrading.size() == varCount());
+
     // Check the order data of mono
     MATHICGB_ASSERT
-      (rawPtr(mono)[orderIndexBegin()] == -computeTotalDegree(mono));
+      (rawPtr(mono)[orderIndexBegin()] == computeDegree(mono));
 #endif
     return true;
   }
 
   void setOrderData(MonoRef mono) const {
-    rawPtr(mono)[orderIndexBegin()] = -computeTotalDegree(mono);      
+    rawPtr(mono)[orderIndexBegin()] = computeDegree(mono);      
     MATHICGB_ASSERT(debugOrderValid(mono));
   }
 
@@ -789,15 +833,27 @@ private:
     const Exponent newExponent,
     MonoRef mono
   ) const {
-    rawPtr(mono)[orderIndexBegin()] += oldExponent - newExponent;
+    MATHICGB_ASSERT(var < varCount());
+    if (mGradingIsTotalDegree)
+      rawPtr(mono)[orderIndexBegin()] += oldExponent - newExponent;
+    else {
+      MATHICGB_ASSERT(mGrading.size() == varCount());
+      rawPtr(mono)[orderIndexBegin()] +=
+        mGrading[var] * (oldExponent - newExponent);
+    }
     MATHICGB_ASSERT(debugOrderValid(mono));
   }
 
-  Exponent computeTotalDegree(ConstMonoRef mono) const {
+  Exponent computeDegree(ConstMonoRef mono) const {
     Exponent degree = 0;
     const auto end = this->end(mono);
-    for (auto it = begin(mono); it != end; ++it)
-      degree += *it;
+    if (mGradingIsTotalDegree) {
+      for (auto it = begin(mono); it != end; ++it)
+        degree -= *it;
+    } else {
+      for (auto var = 0; var < varCount(); ++var)
+        degree += access(mono, exponentsIndexBegin() + var) * mGrading[var];
+    }
     return degree;
   }
 
@@ -807,7 +863,9 @@ private:
   bool debugHashValid(ConstMonoRef mono) const {
     // We cannot call hash() here since it calls this method.
     MATHICGB_ASSERT(hashIndex() < entryCount());
-    MATHICGB_ASSERT(rawPtr(mono)[hashIndex()] == computeHash(mono));
+    // todo: we cannot make this check right now because the legacy
+    // integration with PolyRing can create monomials with unset hash.
+    // MATHICGB_ASSERT(rawPtr(mono)[hashIndex()] == computeHash(mono));
     return true;
   }
 
@@ -871,6 +929,9 @@ private:
   VarIndex orderIndexEnd() const {return mOrderIndexEnd;}
   VarIndex hashIndex() const {return mOrderIndexEnd;}
 
+  VarIndex lastEntryIndex() const {return hashIndex();}
+  VarIndex beforeFirstIndex() const {return static_cast<VarIndex>(-1);}
+
   const VarIndex mVarCount;
   const VarIndex mOrderEntryCount;
   const VarIndex mOrderIndexBegin;
@@ -878,6 +939,15 @@ private:
 
   /// Take dot product of exponents with this vector to get hash value.
   std::vector<HashValue> mHashCoefficients;
+
+  /// This is initialized before mGrading, so it has to be ordered
+  /// above mGrading.
+  const bool mGradingIsTotalDegree;
+
+  /// The degree of a monomial is the dot product of the exponent
+  /// vector with this vector. If mGradingIsTotalDegree is true then
+  /// mGrading is empty but implicitly it is a vector of ones.
+  std::vector<Exponent> mGrading;
 };
 
 #endif
diff --git a/src/mathicgb/PolyRing.cpp b/src/mathicgb/PolyRing.cpp
index 8ab828e..3fa8ba7 100755
--- a/src/mathicgb/PolyRing.cpp
+++ b/src/mathicgb/PolyRing.cpp
@@ -15,6 +15,39 @@ bool PolyRing::hashValid(const_monomial m) const {
   return monomialHashValue(m) == computeHashValue(m);
 }
 
+PolyRing::PolyRing(
+  coefficient p0,
+  int nvars,
+  const std::vector<exponent>& weights
+):
+  mCharac(p0),
+  mNumVars(nvars),
+  mNumWeights(1),
+  mTopIndex(nvars + mNumWeights),
+  mHashIndex(nvars + mNumWeights + 1),
+  mMaxMonomialSize(nvars + mNumWeights + 2),
+  mMaxMonomialByteSize(mMaxMonomialSize * sizeof(exponent)),
+  mMonomialPool(mMaxMonomialByteSize),
+  mTotalDegreeGradedOnly(false)
+#ifdef MATHICGB_USE_MONOID
+  , mMonoid(weights)
+#endif
+{
+  MATHICGB_ASSERT(weights.size() == nvars);
+  mTotalDegreeGradedOnly = true;
+  for (size_t i = 0; i < nvars; ++i)
+    if (weights[i] != 1)
+      mTotalDegreeGradedOnly = false;
+  mWeights.resize(nvars);
+  for (size_t i = 0; i < nvars; ++i)
+    mWeights[i] = -weights[i];
+
+  resetCoefficientStats();
+  srand(0);
+  for (size_t i=0; i<mNumVars; i++)
+    mHashVals.push_back(static_cast<HashValue>(rand()));
+}
+
 PolyRing::PolyRing(coefficient p0,
                    int nvars,
                    int nweights)
@@ -27,7 +60,12 @@ PolyRing::PolyRing(coefficient p0,
     mMaxMonomialByteSize(mMaxMonomialSize * sizeof(exponent)),
     mMonomialPool(mMaxMonomialByteSize),
     mTotalDegreeGradedOnly(nweights == 1)
+#ifdef MATHICGB_USE_MONOID
+    , mMonoid(nvars)
+#endif
 {
+  MATHICGB_ASSERT(nweights == 1);
+
   // set weights to the default value -1
   mWeights.resize(mNumVars * mNumWeights);
   std::fill(mWeights.begin(), mWeights.end(), static_cast<exponent>(-1));
@@ -108,9 +146,13 @@ void PolyRing::monomialEi(size_t i, Monomial &result) const
 
 void PolyRing::monomialMultTo(Monomial &a, ConstMonomial b) const
 {
+#ifdef MATHICGB_USE_MONOID
+  monoid().multiplyInPlace(b, a);
+#else
   // a *= b
   for (size_t i = mHashIndex; i != static_cast<size_t>(-1); --i)
     a[i] += b[i];
+#endif
 }
 
 
@@ -354,20 +396,17 @@ PolyRing *PolyRing::read(std::istream &i)
   charac = static_cast<exponent>(characInt);
   i >> mNumVars;
   i >> mNumWeights;
-  PolyRing* R = new PolyRing(charac, mNumVars, mNumWeights);
+  MATHICGB_ASSERT(mNumWeights == 1);
+
+  std::vector<exponent> weights(mNumWeights);
   int wtlen = mNumVars * mNumWeights;
-  R->mWeights.resize(wtlen);
-  R->mTotalDegreeGradedOnly = (mNumWeights == 1);
-  for (int j=0; j <mNumVars * mNumWeights; j++) {
-    exponent a;
+  weights.resize(wtlen);
+  for (int j=0; j < mNumVars * mNumWeights; j++) {
     int64 aInt;
     i >> aInt;
-    a = static_cast<exponent>(aInt);
-    R->mWeights[j] = -a;
-    if (R->mWeights[j] != -1)
-      R->mTotalDegreeGradedOnly = false;
+    weights[j] = static_cast<exponent>(aInt);
   }
-  return R;
+  return new PolyRing(charac, mNumVars, weights);
 }
 
 void PolyRing::write(std::ostream &o) const
diff --git a/src/mathicgb/PolyRing.hpp b/src/mathicgb/PolyRing.hpp
index 3aa55ab..bc176f7 100755
--- a/src/mathicgb/PolyRing.hpp
+++ b/src/mathicgb/PolyRing.hpp
@@ -3,6 +3,10 @@
 #ifndef _polyRing_h_
 #define _polyRing_h_
 
+#ifdef MATHICGB_USE_MONOID
+#include "MonoMonoid.hpp"
+#endif
+
 #include <assert.h>
 #include <string>
 #include <vector>
@@ -11,7 +15,6 @@
 #include <cstring>
 #include <limits>
 
-#define MATHICGB_USE_MONOID
 
 #define LT (-1)
 #define EQ 0
@@ -115,6 +118,9 @@ T modularNegativeNonZero(T a, T modulus) {
 typedef int32 exponent ;
 typedef uint32 HashValue;
 typedef long coefficient;
+#ifdef MATHICGB_USE_MONOID
+typedef MonoMonoid<exponent> Monoid;
+#endif
 
 typedef exponent* vecmonomial; // includes a component
 typedef coefficient const_coefficient;
@@ -146,6 +152,12 @@ public:
 
   exponent component() const { return *mValue; }
 
+#ifdef MATHICGB_USE_MONOID
+  operator Monoid::ConstMonoRef() const {
+    return Monoid::toRef(mValue);
+  }
+#endif
+
 private:
   const exponent& operator[](size_t index) const { return mValue[index]; }
   const exponent& operator*() const { return *mValue; }
@@ -177,6 +189,12 @@ public:
   exponent * unsafeGetRepresentation() { return const_cast<exponent *>(mValue); }
   exponent const * unsafeGetRepresentation() const { return mValue; }
 
+#ifdef MATHICGB_USE_MONOID
+  operator Monoid::MonoRef() {
+    return Monoid::toRef(unsafeGetRepresentation());
+  }
+#endif
+
 private:
   const exponent& operator[](size_t index) const { return mValue[index]; }
   exponent& operator[](size_t index) { return unsafeGetRepresentation()[index]; }
@@ -212,6 +230,7 @@ struct term {
 
 class PolyRing {
 public:
+  PolyRing(coefficient charac, int nvars, const std::vector<exponent>& weights);
   PolyRing(coefficient charac, int nvars, int nweights);
   ~PolyRing() {}
 
@@ -548,8 +567,8 @@ private:
   bool mTotalDegreeGradedOnly;
 
 #ifdef MATHICGB_USE_MONOID
-  const MonoMonoid& monoid() const {return mMonoid;}
-  MonoMonoid mMonoid;
+  const Monoid& monoid() const {return mMonoid;}
+  Monoid mMonoid;
 #endif
 };
 
@@ -670,6 +689,9 @@ inline void PolyRing::monomialMult(ConstMonomial a,
                                    ConstMonomial b, 
                                    Monomial &result) const
 {
+#ifdef MATHICGB_USE_MONOID
+  monoid().multiply(a, b, result);
+#else
   for (size_t i = mHashIndex; i != static_cast<size_t>(-1); --i)
     result[i] = a[i] + b[i];
   MATHICGB_ASSERT(computeHashValue(result) ==
@@ -687,6 +709,7 @@ inline void PolyRing::monomialMult(ConstMonomial a,
     *presult++ = *pa++ + *pb++;
   //    result[i] = a[i] + b[i];
 #endif
+#endif
 }
 
 inline void PolyRing::setWeightsOnly(Monomial& a1) const
@@ -704,6 +727,9 @@ inline void PolyRing::setWeightsOnly(Monomial& a1) const
 }
 
 inline HashValue PolyRing::computeHashValue(const_monomial a1) const {
+#ifdef MATHICGB_USE_MONOID
+  return monoid().computeHash(a1);
+#else
   const exponent* a = a1.unsafeGetRepresentation();
   HashValue hash = static_cast<HashValue>(*a);
   a++;
@@ -713,6 +739,7 @@ inline HashValue PolyRing::computeHashValue(const_monomial a1) const {
   // when storing a hash value as an exponent. Otherwise the hash
   // value that is computed will not match the stored hash value.
   return static_cast<exponent>(hash);
+#endif
 }
 
 inline void PolyRing::setHashOnly(Monomial& a1) const
@@ -724,6 +751,9 @@ inline void PolyRing::setHashOnly(Monomial& a1) const
 inline int PolyRing::monomialCompare(ConstMonomial a, ConstMonomial b) const
 // returns LT, EQ or GT
 {
+#ifdef MATHICGB_USE_MONOID
+  return monoid().compare(a, b);
+#else
   for (size_t i = mTopIndex; i != static_cast<size_t>(-1); --i)
     {
       auto cmp = a[i] - b[i];
@@ -731,22 +761,20 @@ inline int PolyRing::monomialCompare(ConstMonomial a, ConstMonomial b) const
       if (cmp > 0) return LT;
     }
   return EQ;
+#endif
 }
 
 inline bool PolyRing::monomialIsDivisibleBy(ConstMonomial a,
                                             ConstMonomial b) const
 {
-  // returns truue if b divides a, in this case, result is set to b//a.
-  //  for (int i = mNumVars; i >= 1; --i)
-  //    {
-  //      int c = a[i] - b[i];
-  //      if (c < 0) return false;
-  //    }
+#ifdef MATHICGB_USE_MONOID
+  return monoid().divides(b, a);
+#else
   for (size_t i = 1; i<= mNumVars; i++)
     if (a[i] < b[i])
       return false;
-
   return true;
+#endif
 }
 
 inline bool PolyRing::monomialDivide(ConstMonomial a, 
diff --git a/src/test/MonoMonoid.cpp b/src/test/MonoMonoid.cpp
index 8d4f2c5..241fb5d 100755
--- a/src/test/MonoMonoid.cpp
+++ b/src/test/MonoMonoid.cpp
@@ -381,7 +381,7 @@ TEST(MonoMonoid, MultiplyDivide) {
     m.divide(mono, mono, mono);
     MATHICGB_ASSERT(m.isIdentity(mono));
 
-    // Check that negative exponents work
+    // Check that negative exponents work.
     m.divideToNegative(a, b, mono);
     m.multiply(a, mono, mono);
     ASSERT_TRUE(m.equal(mono, b));
diff --git a/src/test/QuadMatrixBuilder.cpp b/src/test/QuadMatrixBuilder.cpp
index 8aaf1eb..413fba1 100755
--- a/src/test/QuadMatrixBuilder.cpp
+++ b/src/test/QuadMatrixBuilder.cpp
@@ -56,7 +56,7 @@ namespace {
 
 TEST(QuadMatrixBuilder, Empty) {
   // test a builder with no rows and no columns
-  PolyRing ring(2, 0, 0);
+  PolyRing ring(2, 0, 1);
   QuadMatrixBuilder::Map map(ring);
   QuadMatrixBuilder::MonomialsType monoLeft;
   QuadMatrixBuilder::MonomialsType monoRight;

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