[mathicgb] 182/393: An S-pair aA-bB now has aA set as the reducer instead of using some other reducer for the cancelling term. Another S-pair aA-cC can then also be simplified to jsut cC without adding the reducer aA, as it is the same one. Due to a non-trivial interaction with the S-pair elimination/choice, this is guaranteed to simplify all S-pairs and the reducer aA is guaranteed to always be the preferred reducer that would have been used for that monomial anyway. For hcyclic8 this is a 5% speedup and it reduces the number of non-zero entries in the matrix by 6%. There is also now a new log F4MatrixEntryCount that counts the number of non-zero entries across all matrices, which is how I produced the 6% figure.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:57 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 5f7e5ac3482799f15bfd9216b8643181d5875d77
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Wed Mar 6 18:10:30 2013 +0100

    An S-pair aA-bB now has aA set as the reducer instead of using some other reducer for the cancelling term. Another S-pair aA-cC can then also be simplified to jsut cC without adding the reducer aA, as it is the same one. Due to a non-trivial interaction with the S-pair elimination/choice, this is guaranteed to simplify all S-pairs and the reducer aA is guaranteed to always be the preferred reducer that would have been used for that monomial anyway. For hcyclic8 this is a 5% speedup an [...]
---
 src/mathicgb/F4MatrixBuilder2.cpp | 77 +++++++++++++++++++++++++++++++++++++++
 src/mathicgb/F4MatrixBuilder2.hpp |  4 +-
 src/mathicgb/F4Reducer.cpp        |  7 ++++
 3 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/src/mathicgb/F4MatrixBuilder2.cpp b/src/mathicgb/F4MatrixBuilder2.cpp
index 7b00296..11f7317 100755
--- a/src/mathicgb/F4MatrixBuilder2.cpp
+++ b/src/mathicgb/F4MatrixBuilder2.cpp
@@ -81,6 +81,11 @@ void F4MatrixBuilder2::addSPolynomialToMatrix(
   RowTask task;
   task.poly = &polyA;
   task.sPairPoly = &polyB;
+  task.desiredLead = ring().allocMonomial();
+  ring().monomialLeastCommonMultiple(
+    task.poly->getLeadMonomial(),
+    task.sPairPoly->getLeadMonomial(),
+    task.desiredLead);
   mTodo.push_back(task);
 }
 
@@ -119,6 +124,68 @@ void F4MatrixBuilder2::buildMatrixAndClear(QuadMatrix& quadMatrix) {
     return;
   }
 
+  // Use halves of S-pairs as reducers to decrease the number of entries that
+  // need to be looked up.
+  tbb::parallel_sort(mTodo.begin(), mTodo.end(),
+    [&](const RowTask& a, const RowTask& b)
+  {
+    if (a.sPairPoly == 0)
+      return b.sPairPoly != 0;
+    else
+      return ring().monomialLT(a.desiredLead, b.desiredLead);
+  });
+  const auto size = mTodo.size();
+  for (size_t i = 0; i < size;) {
+    if (mTodo[i].sPairPoly == 0) {
+      ++i;
+      continue;
+    }
+    MATHICGB_ASSERT(!mTodo[i].desiredLead.isNull());
+    MATHICGB_ASSERT(ColReader(mMap).find(mTodo[i].desiredLead).first == 0);
+
+    // Create column for the lead term that cancels in the S-pair
+    if (mIsColumnToLeft.size() >= std::numeric_limits<ColIndex>::max())
+      throw std::overflow_error("Too many columns in QuadMatrix");
+    const auto newIndex = static_cast<ColIndex>(mIsColumnToLeft.size());
+    const auto inserted =
+      mMap.insert(std::make_pair(mTodo[i].desiredLead, newIndex));
+    mIsColumnToLeft.push_back(true);
+    const auto& mono = inserted.first.second;
+
+    // Schedule the two parts of the S-pair as separate rows. This adds a row
+    // while creating the column in the hash table without adding a reducer
+    // removes a row, effectively making this operation equivalent to taking
+    // half of the S-pair and using it as a reducer.
+    RowTask newTask = {};
+    newTask.sPairPoly = 0;
+    newTask.poly = mTodo[i].sPairPoly;
+    newTask.desiredLead = ring().allocMonomial();
+    ring().monomialCopy(mono, newTask.desiredLead);
+
+    // Now we can strip off any part of an S-pair with the same cancelling lead
+    // term that equals a or b since those rows are in the matrix.
+    const Poly* const a = mTodo[i].poly;
+    const Poly* const b = mTodo[i].sPairPoly;
+
+    mTodo[i].sPairPoly = 0;
+
+    mTodo.push_back(newTask);
+    for (++i; i < size; ++i) {
+      if (mTodo[i].sPairPoly == 0)
+        continue;
+      MATHICGB_ASSERT(!mTodo[i].desiredLead.isNull());
+      if (!ring().monomialEQ(mTodo[i].desiredLead, mono))
+        break;
+      if (mTodo[i].poly == a || mTodo[i].poly == b) {
+        mTodo[i].poly = mTodo[i].sPairPoly;
+        mTodo[i].sPairPoly = 0;
+      } else if (mTodo[i].sPairPoly == a || mTodo[i].sPairPoly == b) {
+        mTodo[i].sPairPoly = 0;
+      } else
+        MATHICGB_ASSERT(false);
+    }
+  }
+
   // Process pending rows until we are done. Note that the methods
   // we are calling here can add more pending items.
 
@@ -145,6 +212,16 @@ void F4MatrixBuilder2::buildMatrixAndClear(QuadMatrix& quadMatrix) {
     auto& data = threadData.local();
     const auto& poly = *task.poly;
 
+    // It is perfectly permissible for task.sPairPoly to be non-null. The
+    // assert is there because of an interaction between S-pair
+    // elimination/choice and the use of halves of S-pairs as reducers. The
+    // current effect of these is that *all* S-pairs have a component split
+    // off so that sPairPoly is always null (this is non-trivial to
+    // realize). So if this assert goes off, you've messed that interaction
+    // up somehow or you are using this class in some new way. So you can
+    // remove the assert if necessary.
+    MATHICGB_ASSERT(task.sPairPoly == 0);
+
     if (task.sPairPoly != 0) {
       ring().monomialColons(
         poly.getLeadMonomial(),
diff --git a/src/mathicgb/F4MatrixBuilder2.hpp b/src/mathicgb/F4MatrixBuilder2.hpp
index 15a1bab..0828505 100755
--- a/src/mathicgb/F4MatrixBuilder2.hpp
+++ b/src/mathicgb/F4MatrixBuilder2.hpp
@@ -73,12 +73,12 @@ private:
   /// Represents the task of adding a row to the matrix. If sPairPoly is null
   /// then the row to add is multiply * poly. Otherwise, the row to add is
   ///   multiply * poly - sPairMultiply * sPairPoly
-  /// where sPairMultiply makes the lead terms cancel.
+  /// where multiply and sPairMultiply are such that the leading terms become
+  /// desiredLead.
   struct RowTask {
     monomial desiredLead; // multiply monomial onto poly to get this lead
     const Poly* poly;
     const Poly* sPairPoly;
-    monomial sPairMultiply;
   };
   typedef tbb::parallel_do_feeder<RowTask> TaskFeeder;
 
diff --git a/src/mathicgb/F4Reducer.cpp b/src/mathicgb/F4Reducer.cpp
index 964f548..656ae49 100755
--- a/src/mathicgb/F4Reducer.cpp
+++ b/src/mathicgb/F4Reducer.cpp
@@ -24,6 +24,11 @@ MATHICGB_DEFINE_LOG_DOMAIN(
   "Count number of bottom (reducee) rows in F4 matrices."
 );
 
+MATHICGB_DEFINE_LOG_DOMAIN(
+  F4MatrixEntries,
+  "Count number of non-zero entries in F4 matrices."
+);
+
 F4Reducer::F4Reducer(const PolyRing& ring, Type type):
   mType(type),
   mFallback(Reducer::makeReducer(Reducer::Reducer_BjarkeGeo, ring)),
@@ -122,6 +127,7 @@ void F4Reducer::classicReduceSPolySet(
     MATHICGB_LOG_INCREMENT_BY(F4MatrixRows, qm.rowCount());
     MATHICGB_LOG_INCREMENT_BY(F4MatrixTopRows, qm.topLeft.rowCount());
     MATHICGB_LOG_INCREMENT_BY(F4MatrixBottomRows, qm.bottomLeft.rowCount());
+    MATHICGB_LOG_INCREMENT_BY(F4MatrixEntries, qm.entryCount());
     saveMatrix(qm);
     reduced = F4MatrixReducer(basis.ring().charac()).
       reducedRowEchelonFormBottomRight(qm);
@@ -186,6 +192,7 @@ void F4Reducer::classicReducePolySet
     MATHICGB_LOG_INCREMENT_BY(F4MatrixRows, qm.rowCount());
     MATHICGB_LOG_INCREMENT_BY(F4MatrixTopRows, qm.topLeft.rowCount());
     MATHICGB_LOG_INCREMENT_BY(F4MatrixBottomRows, qm.bottomLeft.rowCount());
+    MATHICGB_LOG_INCREMENT_BY(F4MatrixEntries, qm.entryCount());
     saveMatrix(qm);
     reduced = F4MatrixReducer(basis.ring().charac()).
       reducedRowEchelonFormBottomRight(qm);

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