[mathicgb] 27/393: Added support for sorting columns in the F4 QuadMatrixBuilder + tests.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:27 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 69ff7f8cee07e2596b5548f7b5c54cb4e1bbc165
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Wed Sep 26 12:45:37 2012 +0200
Added support for sorting columns in the F4 QuadMatrixBuilder + tests.
---
src/mathicgb/FreeModuleOrder.cpp | 2 +-
src/mathicgb/FreeModuleOrder.hpp | 3 ++
src/mathicgb/Ideal.hpp | 4 +-
src/mathicgb/QuadMatrixBuilder.cpp | 75 +++++++++++++++++++++++++++++++++++++
src/mathicgb/QuadMatrixBuilder.hpp | 13 ++++++-
src/mathicgb/SparseMatrix.hpp | 15 +++++---
src/test/QuadMatrixBuilder.cpp | 77 ++++++++++++++++++++++++++++++++++++++
7 files changed, 180 insertions(+), 9 deletions(-)
diff --git a/src/mathicgb/FreeModuleOrder.cpp b/src/mathicgb/FreeModuleOrder.cpp
index e7297d8..e3e09f9 100755
--- a/src/mathicgb/FreeModuleOrder.cpp
+++ b/src/mathicgb/FreeModuleOrder.cpp
@@ -697,7 +697,7 @@ void FreeModuleOrder::displayOrderTypes(std::ostream &o)
o << " 7 IndexDown SchreyerGrevLex" << std::endl;
}
-FreeModuleOrder *FreeModuleOrder::makeOrder(FreeModuleOrderType type, const Ideal *I)
+FreeModuleOrder* FreeModuleOrder::makeOrder(FreeModuleOrderType type, const Ideal* I)
{
int i;
if (type == 0)
diff --git a/src/mathicgb/FreeModuleOrder.hpp b/src/mathicgb/FreeModuleOrder.hpp
index a59bd45..a4349ab 100755
--- a/src/mathicgb/FreeModuleOrder.hpp
+++ b/src/mathicgb/FreeModuleOrder.hpp
@@ -43,6 +43,9 @@ public:
virtual std::auto_ptr<SigSPairQueue>
createSigSPairQueue(GroebnerBasis const& basis) const = 0;
+ /// @todo: We need at least an enum to make this clearer and the return type
+ /// should be a smart pointer since the client needs to deallocate
+ /// that memory.
static FreeModuleOrder* makeOrder(FreeModuleOrderType type, const Ideal* I);
static void displayOrderTypes(std::ostream &o);
diff --git a/src/mathicgb/Ideal.hpp b/src/mathicgb/Ideal.hpp
old mode 100644
new mode 100755
index 24e86f0..e9105a9
--- a/src/mathicgb/Ideal.hpp
+++ b/src/mathicgb/Ideal.hpp
@@ -22,10 +22,10 @@ public:
static Ideal *parse(std::istream &i); // reads ring, #gens, each generator in turn
void display(std::ostream &o, bool print_comp) const; // inverse operation
- const PolyRing & ring() const { return mRing; }
+ const PolyRing& ring() const { return mRing; }
const PolyRing *getPolyRing() const { return &mRing; }
- const std::vector<Poly *> & viewGenerators() { return mGenerators; }
+ const std::vector<Poly *>& viewGenerators() { return mGenerators; }
const Poly *getPoly(size_t i) const { return mGenerators[i]; }
size_t size() const { return mGenerators.size(); }
diff --git a/src/mathicgb/QuadMatrixBuilder.cpp b/src/mathicgb/QuadMatrixBuilder.cpp
index b7dc8d6..32d5a98 100755
--- a/src/mathicgb/QuadMatrixBuilder.cpp
+++ b/src/mathicgb/QuadMatrixBuilder.cpp
@@ -1,6 +1,7 @@
#include "stdinc.h"
#include "QuadMatrixBuilder.hpp"
+#include "FreeModuleOrder.hpp"
#include <mathic.h>
#include <sstream>
@@ -77,6 +78,80 @@ QuadMatrixBuilder::ColIndex QuadMatrixBuilder::createColumnRight
(findColumn(monomialToBeCopied).rightIndex() == rightColCount() - 1);
}
+namespace {
+ class ColumnComparer {
+ public:
+ ColumnComparer(const FreeModuleOrder& order): mOrder(order) {}
+
+ typedef QuadMatrixBuilder::ColIndex ColIndex;
+ typedef std::pair<monomial, ColIndex> Pair;
+ bool operator()(const Pair& a, const Pair b) const {
+ return mOrder.signatureCompare(a.first, b.first) == GT;
+ }
+
+ private:
+ const FreeModuleOrder& mOrder;
+ };
+
+ // The purpose of this function is to avoid code duplication for
+ // left/right variants.
+ void sortColumns
+ (const FreeModuleOrder& order,
+ std::vector<monomial>& monomials,
+ SparseMatrix& topMatrix,
+ SparseMatrix& bottomMatrix)
+ {
+ typedef SparseMatrix::ColIndex ColIndex;
+ MATHICGB_ASSERT(topMatrix.colCount() == bottomMatrix.colCount());
+ const ColIndex colCount = topMatrix.colCount();
+
+ // Monomial needs to be non-const as we are going to put these
+ // monomials back into the vector of monomials which is not const.
+ std::vector<std::pair<monomial, ColIndex> > columns;
+ columns.reserve(colCount);
+ for (size_t col = 0; col < colCount; ++col)
+ columns.push_back(std::make_pair(monomials[col], col));
+ std::sort(columns.begin(), columns.end(), ColumnComparer(order));
+
+ // Reorder monomials associated to each column to be in sorted order
+ MATHICGB_ASSERT(columns.size() == colCount);
+ MATHICGB_ASSERT(monomials.size() == colCount);
+ for (size_t col = 0; col < colCount; ++col) {
+ MATHICGB_ASSERT(col == 0 || order.signatureCompare
+ (columns[col - 1].first, columns[col].first) == GT);
+ monomials[col] = columns[col].first;
+ }
+
+ // Construct permutation of indices to match permutation of monomials
+ std::vector<ColIndex> permutation(colCount);
+ for (size_t col = 0; col < colCount; ++col) {
+ // The monomial for column columns[col].second is now the
+ // monomial for col, so we need the inverse map for indices.
+ permutation[columns[col].second] = col;
+ }
+
+ // Change indices to match the permutation done on the columns
+ typedef SparseMatrix::AllColIndicesIterator Iter;
+ for (int doTop = 0; doTop < 2; ++doTop) {
+ SparseMatrix& matrix = doTop ? topMatrix : bottomMatrix;
+ Iter it = matrix.allColIndicesBegin();
+ Iter end = matrix.allColIndicesEnd();
+ for (; it != end; ++it) {
+ MATHICGB_ASSERT(*it < colCount);
+ *it = permutation[*it];
+ }
+ }
+ }
+}
+
+void QuadMatrixBuilder::sortColumnsLeft(const FreeModuleOrder& order) {
+ sortColumns(order, mMonomialsLeft, mTopLeft, mBottomLeft);
+}
+
+void QuadMatrixBuilder::sortColumnsRight(const FreeModuleOrder& order) {
+ sortColumns(order, mMonomialsRight, mTopRight, mBottomRight);
+}
+
void QuadMatrixBuilder::print(std::ostream& out) const {
mathic::ColumnPrinter printer;
printer.addColumn(true, "", "");
diff --git a/src/mathicgb/QuadMatrixBuilder.hpp b/src/mathicgb/QuadMatrixBuilder.hpp
index 18adbaf..788f1a7 100755
--- a/src/mathicgb/QuadMatrixBuilder.hpp
+++ b/src/mathicgb/QuadMatrixBuilder.hpp
@@ -7,6 +7,7 @@
#include <map>
#include <string>
#include <ostream>
+class FreeModuleOrder;
/** Builder for a set of 4 sub-matrices that fit together and where
columns have an associated monomial.
@@ -132,7 +133,7 @@ class QuadMatrixBuilder {
mBottomRight.rowDone();
}
- // *** Creating columns
+ // *** Creating and reordering columns
// Unlike the interface for SparseMatrix, here you have to create
// columns before you can append entries in those columns. All
// passed in monomials are copied so that ownership of the memory is
@@ -148,6 +149,16 @@ class QuadMatrixBuilder {
this monomial on the left or on the right. */
ColIndex createColumnRight(const_monomial monomialToBeCopied);
+ /** Sorts the left columns to be decreasing with respect to
+ order. Also updates the column indices already in the matrix to
+ reflect the new ordering. */
+ void sortColumnsLeft(const FreeModuleOrder& order);
+
+ /** Sorts the right columns to be decreasing with respect to
+ order. Also updates the column indices already in the matrix to
+ reflect the new ordering. */
+ void sortColumnsRight(const FreeModuleOrder& order);
+
// *** Querying columns
diff --git a/src/mathicgb/SparseMatrix.hpp b/src/mathicgb/SparseMatrix.hpp
index 0c38b3c..808c266 100755
--- a/src/mathicgb/SparseMatrix.hpp
+++ b/src/mathicgb/SparseMatrix.hpp
@@ -74,10 +74,9 @@ class SparseMatrix {
return mRowOffsets[row] == mRowOffsets[row + 1];
}
- /** Removes the leading trimThisMany columns.
-
- The columns are removed by replacing all column indices col by col
- - trimThisMany. No entry can have a column index less than
+ /** Removes the leading trimThisMany columns. The columns are
+ removed by replacing all column indices col by col -
+ trimThisMany. No entry can have a column index less than
trimThisMany, even if the scalar of that entry is set to zero. */
void trimLeadingZeroColumns(ColIndex trimThisMany) {
MATHICGB_ASSERT(trimThisMany <= colCount());
@@ -128,6 +127,7 @@ class SparseMatrix {
return out.str();
}
+
/** Adds a new row that contains all terms that have been appended
since the last time a row was added or the matrix was created. */
void rowDone() {
@@ -345,7 +345,12 @@ class SparseMatrix {
return mColIndices;
}
- private:
+ typedef std::vector<ColIndex>::iterator AllColIndicesIterator;
+ AllColIndicesIterator allColIndicesBegin() {return mColIndices.begin();}
+ AllColIndicesIterator allColIndicesEnd() {return mColIndices.end();}
+
+
+private:
friend class RowIterator;
ColIndex indexAtOffset(size_t offset) const {
diff --git a/src/test/QuadMatrixBuilder.cpp b/src/test/QuadMatrixBuilder.cpp
index c2dede2..726741b 100755
--- a/src/test/QuadMatrixBuilder.cpp
+++ b/src/test/QuadMatrixBuilder.cpp
@@ -4,6 +4,8 @@
#include "mathicgb/PolyRing.hpp"
#include "mathicgb/QuadMatrixBuilder.hpp"
#include "mathicgb/io-util.hpp"
+#include "mathicgb/FreeModuleOrder.hpp"
+#include "mathicgb/Ideal.hpp"
#include <gtest/gtest.h>
namespace {
@@ -120,3 +122,78 @@ TEST(QuadMatrixBuilder, ColumnQuery) {
}
}
}
+
+TEST(QuadMatrixBuilder, SortColumns) {
+ // construct builder and reverse lex order
+ std::auto_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
+ Ideal ideal(*ring);
+ std::auto_ptr<FreeModuleOrder> order(FreeModuleOrder::makeOrder(1, &ideal));
+
+ // one row top, no rows bottom, no columns
+ {
+ QuadMatrixBuilder b(*ring);
+ b.rowDoneTopLeftAndRight();
+ b.sortColumnsLeft(*order);
+ b.sortColumnsRight(*order);
+ const char* matrixStr =
+ "Left columns:\n"
+ "Right columns:\n"
+ "0: | 0: \n"
+ " | \n"
+ "matrix with no rows | matrix with no rows\n";
+ ASSERT_EQ(matrixStr, b.toString());
+ }
+
+ {
+ QuadMatrixBuilder b(*ring);
+ createColumns("<0>+a<0>", "b<0>+bcd<0>+bc<0>", b);
+ b.appendEntryTopLeft(0,1);
+ b.appendEntryTopLeft(1,2);
+ b.appendEntryTopRight(0,3);
+ b.appendEntryTopRight(1,4);
+ b.appendEntryTopRight(2,5);
+ b.rowDoneTopLeftAndRight();
+
+ b.appendEntryBottomLeft(0,6);
+ b.appendEntryBottomLeft(1,7);
+ b.appendEntryBottomRight(0,8);
+ b.appendEntryBottomRight(1,9);
+ b.appendEntryBottomRight(2,10);
+ b.rowDoneBottomLeftAndRight();
+
+ const char* matrixStr1 =
+ "Left columns: 1 a\n"
+ "Right columns: b bcd bc\n"
+ "0: 0#1 1#2 | 0: 0#3 1#4 2#5 \n"
+ " | \n"
+ "0: 0#6 1#7 | 0: 0#8 1#9 2#10\n";
+ ASSERT_EQ(matrixStr1, b.toString());
+
+ const char* matrixStr2 =
+ "Left columns: a 1\n"
+ "Right columns: b bcd bc\n"
+ "0: 1#1 0#2 | 0: 0#3 1#4 2#5 \n"
+ " | \n"
+ "0: 1#6 0#7 | 0: 0#8 1#9 2#10\n";
+ b.sortColumnsLeft(*order);
+ ASSERT_EQ(matrixStr2, b.toString());
+
+ b.sortColumnsLeft(*order); // sort when already sorted
+ ASSERT_EQ(matrixStr2, b.toString());
+
+ const char* matrixStr3 =
+ "Left columns: a 1\n"
+ "Right columns: bcd bc b\n"
+ "0: 1#1 0#2 | 0: 2#3 0#4 1#5 \n"
+ " | \n"
+ "0: 1#6 0#7 | 0: 2#8 0#9 1#10\n";
+ b.sortColumnsRight(*order);
+ ASSERT_EQ(matrixStr3, b.toString());
+
+ b.sortColumnsRight(*order); // sort when already sorted
+ ASSERT_EQ(matrixStr3, b.toString());
+
+ b.sortColumnsLeft(*order);
+ ASSERT_EQ(matrixStr3, b.toString());
+ }
+}
--
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