[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