[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