[mathicgb] 31/393: Added tests for F4MatrixBuilder and fixed it so that now it seems to work. Also introduced a QuadMatrix class and used it as output of both QuadMatrixBuilder and F4MatrixBuilder.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:58:28 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 ac3506d45bd7114184b41312bc63a8d49d242296
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Thu Sep 27 18:51:28 2012 +0200

    Added tests for F4MatrixBuilder and fixed it so that now it seems to work. Also introduced a QuadMatrix class and used it as output of both QuadMatrixBuilder and F4MatrixBuilder.
---
 Makefile.am                        |  12 +-
 src/mathicgb/F4MatrixBuilder.cpp   | 116 +++++++++++++++++++
 src/mathicgb/F4MatrixBuilder.hpp   | 156 +++++---------------------
 src/mathicgb/F4Reducer.cpp         |  11 +-
 src/mathicgb/PolyBasis.cpp         |   0
 src/mathicgb/QuadMatrix.cpp        |  64 +++++++++++
 src/mathicgb/QuadMatrix.hpp        |  39 +++++++
 src/mathicgb/QuadMatrixBuilder.cpp |  26 +++++
 src/mathicgb/QuadMatrixBuilder.hpp |  22 ++--
 src/test/F4MatrixBuilder.cpp       | 139 +++++++++++++++++++++++
 src/test/QuadMatrixBuilder.cpp     |  46 ++++++++
 src/test/gb-test.cpp               | 223 ++++++++++++++++++-------------------
 src/test/pict.in                   |  12 +-
 13 files changed, 592 insertions(+), 274 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index b1b1a7b..1f12799 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,7 @@
 # autoconf. We use -I to tell aclocal where we put the local macros.
 ACLOCAL_AMFLAGS = -I build/autotools/m4
 
-# Options passed to the C PreProcessor (CPP), NOT the C Plus Plus compiler.
+# Options passed to the C and C++ PreProcessor (CPP) and compiler
 AM_CPPFLAGS = -I${top_srcdir}/
 libmathicgb_la_CPPFLAGS = $(DEPS_CFLAGS)
 
@@ -58,7 +58,8 @@ libmathicgb_la_SOURCES = src/mathicgb/BjarkeGeobucket2.cpp				\
   src/mathicgb/QuadMatrixBuilder.cpp src/mathicgb/TypicalReducer.cpp	\
   src/mathicgb/TypicalReducer.cpp src/mathicgb/F4Reducer.hpp			\
   src/mathicgb/F4Reducer.cpp src/mathicgb/F4MatrixBuilder.hpp			\
-  src/mathicgb/F4MatrixBuilder.cpp
+  src/mathicgb/F4MatrixBuilder.cpp src/mathicgb/QuadMatrix.hpp			\
+  src/mathicgb/QuadMatrix.cpp
 
 # When making a distribution file, Automake knows to include all files
 # that are necessary to build the project. EXTRA_DIST specifies files
@@ -67,8 +68,8 @@ EXTRA_DIST = autogen.sh libs/gtest
 
 bin_PROGRAMS = mgb
 
-# set up the divisor query simulation. Listing the headers in sources
-# ensure that those files are included in distributions.
+# set up the tests. Listing the headers in sources ensure that those
+# files are included in distributions.
 mgb_CPPFLAGS = $(DEPS_CFLAGS)
 mgb_SOURCES = src/cli/GBMain.cpp
 mgb_LDADD = $(top_builddir)/libmathicgb.la
@@ -88,4 +89,5 @@ test_LIBS=
 unittest_SOURCES=src/test/FreeModuleOrderTest.cpp						\
   src/test/gtestInclude.cpp src/test/testMain.cpp src/test/gb-test.cpp	\
   src/test/ideals.cpp src/test/poly-test.cpp src/test/ideals.hpp		\
-  src/test/SparseMatrix.cpp src/test/QuadMatrixBuilder.cpp
+  src/test/SparseMatrix.cpp src/test/QuadMatrixBuilder.cpp				\
+  src/test/F4MatrixBuilder.cpp
diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
index 4394c8b..2605e99 100755
--- a/src/mathicgb/F4MatrixBuilder.cpp
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -1,2 +1,118 @@
 #include "stdinc.h"
 #include "F4MatrixBuilder.hpp"
+
+F4MatrixBuilder::F4MatrixBuilder(const PolyBasis& basis):
+  mBasis(basis), mBuilder(basis.ring()) {}
+
+void F4MatrixBuilder::addTwoRowsForSPairToMatrix(const Poly& polyA, const Poly& polyB) {
+  MATHICGB_ASSERT(!polyA.isZero());
+  MATHICGB_ASSERT(!polyB.isZero());
+
+  monomial lcm = ring().allocMonomial();
+  ring().monomialLeastCommonMultiple
+    (polyA.getLeadMonomial(), polyB.getLeadMonomial(), lcm);
+
+  monomial multiple = ring().allocMonomial();
+
+  ring().monomialDivide(polyA.getLeadMonomial(), lcm, multiple);
+  addRowToMatrix(multiple, polyA);
+
+  ring().monomialDivide(polyB.getLeadMonomial(), lcm, multiple);
+  addRowToMatrix(multiple, polyB);
+
+  ring().freeMonomial(lcm);
+  ring().freeMonomial(multiple);
+}
+
+void F4MatrixBuilder::addRowToMatrix
+(const_monomial multiple, const Poly& poly) {
+  RowTask task;
+  task.useAsReducer = false; // to be updated later
+  task.poly = &poly;
+
+  task.multiple = ring().allocMonomial();
+  ring().monomialCopy(multiple, task.multiple);
+  mTodo.push_back(task);
+}
+
+void F4MatrixBuilder::buildMatrixAndClear(QuadMatrix& matrix) {
+  // todo: detect and remove duplicate input rows.
+  // todo: prefer sparse/old reducers among the inputs.
+  monomial mono = ring().allocMonomial();
+
+  // Decide which input rows are going to be used as reducers and
+  // create pivot columns ahead of time for those reducers so that
+  // we do not add a reducer for those columns later on.
+  typedef std::vector<RowTask>::iterator TaskIter;
+  TaskIter end = mTodo.end();
+  for (TaskIter it = mTodo.begin(); it != end; ++it) {
+    ring().monomialMult(it->multiple, it->poly->getLeadMonomial(), mono);
+    LeftRightColIndex leadCol = mBuilder.findColumn(mono);
+    it->useAsReducer = !leadCol.valid();
+    if (it->useAsReducer) {
+      // create column so we know later on that we already have a
+      // reducer for this column.
+      mBuilder.createColumnLeft(mono);
+    }
+  }
+
+  // Process pending rows until we are done. Note that the methods
+  // we are calling here can add more items to mTodo.
+  while (!mTodo.empty()) {
+    RowTask task = mTodo.back();
+    mTodo.pop_back();
+    if (task.useAsReducer)
+      appendRowTop(task.multiple, *task.poly);
+    else
+      appendRowBottom(task.multiple, *task.poly);
+  }
+
+  mBuilder.buildMatrixAndClear(matrix);
+}
+
+F4MatrixBuilder::LeftRightColIndex
+F4MatrixBuilder::createOrFindColumnOf(const_monomial mono) {
+  LeftRightColIndex colIndex = mBuilder.findColumn(mono);
+  if (colIndex.valid())
+    return colIndex;
+
+  // mono did not already have a column so look for a reducer
+  size_t reducerIndex = mBasis.divisor(mono);
+  if (reducerIndex == static_cast<size_t>(-1))
+    return LeftRightColIndex(mBuilder.createColumnRight(mono), false);
+
+  // schedule the reducer to be added as a row
+  RowTask task;
+  task.poly = &mBasis.poly(reducerIndex);
+  task.useAsReducer = true;
+  task.multiple = ring().allocMonomial();
+  ring().monomialDivideToNegative
+    (mono, task.poly->getLeadMonomial(), task.multiple);
+  mTodo.push_back(task);
+
+  return LeftRightColIndex(mBuilder.createColumnLeft(mono), true);
+}
+
+void F4MatrixBuilder::appendRowTop(const_monomial multiple, const Poly& poly) {
+  monomial mono = ring().allocMonomial();
+  Poly::const_iterator end = poly.end();
+  for (Poly::const_iterator it = poly.begin(); it != end; ++it) {
+    ring().monomialMult(it.getMonomial(), multiple, mono);
+    mBuilder.appendEntryTop(createOrFindColumnOf(mono), it.getCoefficient());
+  }
+  mBuilder.rowDoneTopLeftAndRight();
+  ring().freeMonomial(mono);
+}
+
+void F4MatrixBuilder::appendRowBottom
+(const_monomial multiple, const Poly& poly) {
+  monomial mono = ring().allocMonomial();
+  Poly::const_iterator end = poly.end();
+  for (Poly::const_iterator it = poly.begin(); it != end; ++it) {
+    ring().monomialMult(it.getMonomial(), multiple, mono);
+    mBuilder.appendEntryBottom
+      (createOrFindColumnOf(mono), it.getCoefficient());
+  }
+  mBuilder.rowDoneBottomLeftAndRight();
+  ring().freeMonomial(mono);
+}
diff --git a/src/mathicgb/F4MatrixBuilder.hpp b/src/mathicgb/F4MatrixBuilder.hpp
index 02b9f22..86632f3 100755
--- a/src/mathicgb/F4MatrixBuilder.hpp
+++ b/src/mathicgb/F4MatrixBuilder.hpp
@@ -5,6 +5,7 @@
 #include "Poly.hpp"
 #include "PolyRing.hpp"
 #include "PolyBasis.hpp"
+#include "QuadMatrix.hpp"
 #include <vector>
 
 /** Class for constructing an F4 matrix. This class is reponsible for
@@ -20,153 +21,48 @@ private:
   typedef QuadMatrixBuilder::LeftRightColIndex LeftRightColIndex;
 
 public:
-  F4MatrixBuilder(const PolyBasis& basis):
-    mBasis(basis), mBuilder(basis.ring()) {}
+  F4MatrixBuilder(const PolyBasis& basis);
 
   /** Schedules two rows to be added to the matrix whose linear span
     includes the S-polynomial between polyA and polyB. More precisely,
     the two rows represent (B:A)*polyA and (A:B)*polyB where
     A=lead(polyA) and B=lead(polyB). */
-  void addTwoRowsForSPairToMatrix(const Poly& polyA, const Poly& polyB) {
-    MATHICGB_ASSERT(!polyA.isZero());
-    MATHICGB_ASSERT(!polyB.isZero());
-
-    monomial lcm = ring().allocMonomial();
-    ring().monomialLeastCommonMultiple
-      (polyA.getLeadMonomial(), polyB.getLeadMonomial(), lcm);
-
-    monomial multiple = ring().allocMonomial();
-
-    ring().monomialDivide(polyA.getLeadMonomial(), lcm, multiple);
-    addRowToMatrix(multiple, polyA);
-
-    ring().monomialDivide(polyB.getLeadMonomial(), lcm, multiple);
-    addRowToMatrix(multiple, polyB);
-
-    ring().freeMonomial(lcm);
-    ring().freeMonomial(multiple);
-  }
+  void addTwoRowsForSPairToMatrix(const Poly& polyA, const Poly& polyB);
 
   /** Schedules a row representing multiple*poly to be added to the
       matrix. No ownership is taken, but poly must remain valid until
       the matrix is constructed. multiple is copied so there is no
       requirement there. */
-  void addRowToMatrix(const_monomial multiple, const Poly& poly) {
-    RowTask task;
-    task.useAsReducer = false; // to be updated later
-    task.poly = &poly;
-    task.multiple = ring().allocMonomial();
-    ring().monomialCopy(multiple, task.multiple);
-    mTodo.push_back(task);
-  }
-
-  /** Builds a matrix and returns it as 4 submatrices A, B, C and
-      D. These fit together as
-    
-      A B
-      C D
-
-      where A contains all the pivot rows and columns. The vector tells
-      you which monomial each column in B and D represents. This vector
-      is sorted in descending order using the order from the basis.
-
-      The matrix contains a reducer/pivot for every monomial that can be
-      reduced by the basis and that is present in the matrix. Note that
-      the client-added rows also count as reducers so their lead terms
-      will not get another reducer added automatically -- specifically,
-      adding an S-polynomial will not do what you want because its lead
-      term will have no reducer other than itself. Instead, add the two
-      polynomials that you would have subtracted from each other to form
-      the S-polynomial. */
-  void buildMatricesAndClear
-  (SparseMatrix& topLeft,
-   SparseMatrix& topRight,
-   SparseMatrix& bottomLeft,
-   SparseMatrix& bottomRight,
-   std::vector<monomial> monomialsOfRightColumns)
-  {
-    // todo: sort input rows by sparsity and/or age.
-    // todo: detect and remove duplicate input rows.
-    monomial mono = ring().allocMonomial();
-
-    // Decide which input rows are going to be used as reducers and
-    // create pivot columns ahead of time for those reducers so that
-    // we do not add a reducer for those columns later on.
-    typedef std::vector<RowTask>::iterator TaskIter;
-    TaskIter end = mTodo.end();
-    for (TaskIter it = mTodo.begin(); it != end; ++it) {
-      ring().monomialMult(it->multiple, it->poly->getLeadMonomial(), mono);
-      LeftRightColIndex leadCol = mBuilder.findColumn(mono);
-      it->useAsReducer = !leadCol.valid();
-      if (it->useAsReducer) {
-        // create column so we know later on that we already have a
-        // reducer for this column.
-        createOrFindColumnOf(mono);
-      }
-    }
-
-    // Process pending rows until we are done. Note that the methods
-    // we are calling here can add more items to mTodo.
-    while (!mTodo.empty()) {
-      RowTask task = mTodo.back();
-      mTodo.pop_back();
-      if (task.useAsReducer)
-        appendRowTop(task.multiple, *task.poly);
-      else
-        appendRowBottom(task.multiple, *task.poly);
-    }
-
-    //mBuilder.extractMatricesAndClear
-    //(topLeft, topRight, bottomLeft, bottomRight, monomialsOfRightColumns);
-  }
+  void addRowToMatrix(const_monomial multiple, const Poly& poly);
+
+  /** Builds an F4 matrix to the specifications given. Also clears the
+    information in this object.
+
+    The right columns are ordered by decreasing monomial of that
+    column according to the order from the basis. The left columns are
+    order in some way so that the first entry in each row (the pivot)
+    has a lower index than any other entries in that row.
+
+    The matrix contains a reducer/pivot for every monomial that can be
+    reduced by the basis and that is present in the matrix. Note that
+    the client-added rows also count as reducers so their lead terms
+    will not get another reducer added automatically -- specifically,
+    adding an S-polynomial will not do what you want because its lead
+    term may have no reducer in the matrix other than itself. Instead,
+    add the two polynomials that you would have subtracted from each
+    other to form the S-polynomial - or even better call the method
+    that adds an S-pair for you. */
+  void buildMatrixAndClear(QuadMatrix& matrix);
 
   const PolyRing& ring() const {return mBuilder.ring();}
 
 private:
   /** Returns a left or right column that represents mono. Creates a
       new column and schedules a new row to reduce that column if necessary. */
-  LeftRightColIndex createOrFindColumnOf(const_monomial mono) {
-    LeftRightColIndex colIndex = mBuilder.findColumn(mono);
-    if (colIndex.valid())
-      return colIndex;
-
-    // mono did not already have a column so look for a reducer
-    size_t reducerIndex = mBasis.divisor(mono);
-    if (reducerIndex == static_cast<size_t>(-1))
-      return LeftRightColIndex(mBuilder.createColumnRight(mono), false);
-
-    // schedule the reducer to be added as a row
-    RowTask task;
-    task.poly = &mBasis.poly(reducerIndex);
-    task.useAsReducer = true;
-    task.multiple = ring().allocMonomial();
-    ring().monomialDivideToNegative
-      (mono, task.poly->getLeadMonomial(), task.multiple);
-    mTodo.push_back(task);
-
-    return LeftRightColIndex(mBuilder.createColumnLeft(mono), true);
-  }
-
-  void appendRowTop(const_monomial multiple, const Poly& poly) {
-    monomial mono = ring().allocMonomial();
-    Poly::const_iterator end = poly.end();
-    for (Poly::const_iterator it = poly.begin(); it != end; ++it) {
-      ring().monomialMult(it.getMonomial(), multiple, mono);
-      mBuilder.appendEntryTop(createOrFindColumnOf(mono), it.getCoefficient());
-    }
-    ring().freeMonomial(mono);
-  }
+  LeftRightColIndex createOrFindColumnOf(const_monomial mono);
 
-  void appendRowBottom(const_monomial multiple, const Poly& poly) {
-    monomial mono = ring().allocMonomial();
-    Poly::const_iterator end = poly.end();
-    for (Poly::const_iterator it = poly.begin(); it != end; ++it) {
-      ring().monomialMult(it.getMonomial(), multiple, mono);
-      mBuilder.appendEntryBottom
-        (createOrFindColumnOf(mono), it.getCoefficient());
-    }
-    ring().freeMonomial(mono);
-  }
+  void appendRowTop(const_monomial multiple, const Poly& poly);
+  void appendRowBottom(const_monomial multiple, const Poly& poly);
 
   /// Represents the task of adding a row representing poly*multiple.
   struct RowTask {
diff --git a/src/mathicgb/F4Reducer.cpp b/src/mathicgb/F4Reducer.cpp
index 2a7fc3e..42ed9c3 100755
--- a/src/mathicgb/F4Reducer.cpp
+++ b/src/mathicgb/F4Reducer.cpp
@@ -34,16 +34,11 @@ std::auto_ptr<Poly> F4Reducer::classicReduceSPoly
     mClassicStats = mFallback->classicStats();
   }
 
-  SparseMatrix topLeft;
-  SparseMatrix topRight;
-  SparseMatrix bottomLeft;
-  SparseMatrix bottomRight;
-  std::vector<monomial> monomialsOfRightColumns;
+  QuadMatrix qm;
   {
     F4MatrixBuilder builder(basis);
     builder.addTwoRowsForSPairToMatrix(a, b);
-    builder.buildMatricesAndClear
-      (topLeft, topRight, bottomLeft, bottomRight, monomialsOfRightColumns);
+    builder.buildMatrixAndClear(qm);
   }
 
   return p;
@@ -65,5 +60,5 @@ std::string F4Reducer::description() const {
 }
 
 size_t F4Reducer::getMemoryUse() const {
-  return 0;
+  return 0; // @todo: implement
 }
diff --git a/src/mathicgb/PolyBasis.cpp b/src/mathicgb/PolyBasis.cpp
old mode 100644
new mode 100755
diff --git a/src/mathicgb/QuadMatrix.cpp b/src/mathicgb/QuadMatrix.cpp
new file mode 100755
index 0000000..9395725
--- /dev/null
+++ b/src/mathicgb/QuadMatrix.cpp
@@ -0,0 +1,64 @@
+#include "stdinc.h"
+#include "QuadMatrix.hpp"
+
+#include <ostream>
+#include <sstream>
+#include <mathic.h>
+
+#ifdef MATHICGB_DEBUG
+bool QuadMatrix::debugAssertValid() const {
+  MATHICGB_ASSERT(topLeft.colCount() == bottomLeft.colCount());
+  MATHICGB_ASSERT(topLeft.rowCount() == topRight.rowCount());
+  MATHICGB_ASSERT(topLeft.colCount() == leftColumnMonomials.size());
+
+  MATHICGB_ASSERT(bottomRight.colCount() == topRight.colCount());
+  MATHICGB_ASSERT(bottomRight.rowCount() == bottomLeft.rowCount());
+  MATHICGB_ASSERT(bottomRight.colCount() == rightColumnMonomials.size());   
+  return true;
+}
+#endif
+
+void QuadMatrix::print(std::ostream& out) const {
+  MATHICGB_ASSERT(debugAssertValid());
+
+  // @todo: fix the code duplication here from QuadMatrixBuilder's
+  // string code.
+
+  typedef SparseMatrix::ColIndex ColIndex;
+  mathic::ColumnPrinter printer;
+  printer.addColumn(true, "", "");
+  printer.addColumn(true, " | ", "");
+
+  // column monomials
+  out << "Left columns:";
+  for (ColIndex leftCol = 0; leftCol < topLeft.colCount(); ++leftCol) {
+    out << ' ';
+    ring->monomialDisplay(out, leftColumnMonomials[leftCol], false, true);
+  }
+
+  out << "\nRight columns:";
+  for (ColIndex rightCol = 0; rightCol < topRight.colCount(); ++rightCol) {
+    out << ' ';
+    ring->monomialDisplay(out, rightColumnMonomials[rightCol], false, true);
+  }
+  out << '\n';
+
+  // left side
+  topLeft.print(printer[0]);
+  printer[0] << '\n';
+  bottomLeft.print(printer[0]);
+
+  // right side
+  topRight.print(printer[1]);
+  printer[1] << '\n';
+  bottomRight.print(printer[1]);
+
+  out << printer;
+}
+
+// String representation intended for debugging.
+std::string QuadMatrix::toString() const {
+  std::ostringstream out;
+  print(out);
+  return out.str();
+}
diff --git a/src/mathicgb/QuadMatrix.hpp b/src/mathicgb/QuadMatrix.hpp
new file mode 100755
index 0000000..6c7873b
--- /dev/null
+++ b/src/mathicgb/QuadMatrix.hpp
@@ -0,0 +1,39 @@
+#ifndef MATHICGB_QUAD_MATRIX_GUARD
+#define MATHICGB_QUAD_MATRIX_GUARD
+
+#include "PolyRing.hpp"
+#include "SparseMatrix.hpp"
+#include <vector>
+#include <string>
+class ostream;
+
+/** Represents a matrix composed of 4 sub-matrices that fit together
+  into one matrix divided into top left, top right, bottom left and
+  bottom right. This is a convenient representation of the matrices
+  encountered in the F4 polynomial reduction algorithm.
+
+  So far this is just a data class used as the output of a
+  QuadMatrixBuilder or F4MatrixBuilder. */
+class QuadMatrix {
+public:
+  SparseMatrix topLeft; 
+  SparseMatrix topRight;
+  SparseMatrix bottomLeft;
+  SparseMatrix bottomRight;
+  std::vector<monomial> leftColumnMonomials;
+  std::vector<monomial> rightColumnMonomials;
+  const PolyRing* ring;
+
+  /// Prints whole matrix to out in human-readable format. Useful for
+  /// debugging.
+  void print(std::ostream& out) const;
+
+  /// Shows whole matrix in a string. Useful for debugging.
+  std::string toString() const;
+
+#ifdef MATHICGB_DEBUG
+  bool debugAssertValid() const;
+#endif
+};
+
+#endif
diff --git a/src/mathicgb/QuadMatrixBuilder.cpp b/src/mathicgb/QuadMatrixBuilder.cpp
index 32d5a98..24974e2 100755
--- a/src/mathicgb/QuadMatrixBuilder.cpp
+++ b/src/mathicgb/QuadMatrixBuilder.cpp
@@ -2,6 +2,7 @@
 #include "QuadMatrixBuilder.hpp"
 
 #include "FreeModuleOrder.hpp"
+#include "QuadMatrix.hpp"
 #include <mathic.h>
 #include <sstream>
 
@@ -190,3 +191,28 @@ std::string QuadMatrixBuilder::toString() const {
   print(out);
   return out.str();
 }
+
+void QuadMatrixBuilder::buildMatrixAndClear(QuadMatrix& out) {
+  // we cannot use std::move as the builder is supposed to remain in a
+  // valid state. @todo: consider using a QuadMatrix as the internal
+  // data representation.
+
+  mTopLeft.swap(out.topLeft);
+  mTopRight.swap(out.topRight);
+  mBottomLeft.swap(out.bottomLeft);
+  mBottomRight.swap(out.bottomRight);
+  mMonomialsLeft.swap(out.leftColumnMonomials);
+  mMonomialsRight.swap(out.rightColumnMonomials);
+  out.ring = &ring();
+
+  mTopLeft.clear();
+  mTopRight.clear();
+  mBottomLeft.clear();
+  mBottomRight.clear();
+  mMonomialsLeft.clear();
+  mMonomialsRight.clear();
+
+  mMonomialToCol.clear();
+
+  MATHICGB_ASSERT(out.debugAssertValid());
+}
diff --git a/src/mathicgb/QuadMatrixBuilder.hpp b/src/mathicgb/QuadMatrixBuilder.hpp
index 788f1a7..4255b7d 100755
--- a/src/mathicgb/QuadMatrixBuilder.hpp
+++ b/src/mathicgb/QuadMatrixBuilder.hpp
@@ -8,20 +8,12 @@
 #include <string>
 #include <ostream>
 class FreeModuleOrder;
+class QuadMatrix;
 
-/** Builder for a set of 4 sub-matrices that fit together and where
-  columns have an associated monomial.
-
-  The sub-matrices are top left, top right, bottom left and bottom
-  right. The interface ensures that these fit together in terms of
-  number of rows and columns so that they could form one bigger
-  matrix.
-
-  Columns have an associated monomial and it is possible to search for
-  the column with a given monomial.
-
-  This matrix is intended to be used while constructing matrices to
-  reduce polynomials using the F4 algorithm of Faugere. */
+/** Builder for QuadMatrix. This is not quite the builder pattern in
+  that the interface is not virtual and the implementation cannot be
+  swapped out - it only follows the builder pattern in that it is a
+  class that allows step-wise construction of a final product. */
 class QuadMatrixBuilder {
  public:
   typedef SparseMatrix::RowIndex RowIndex;
@@ -219,6 +211,10 @@ class QuadMatrixBuilder {
     return topRight().colCount();
   }
 
+  /// Puts the built matrix into out and sets the builder to a state
+  /// with no columns and no rows.
+  void buildMatrixAndClear(QuadMatrix& out);
+
 private:
   // Store the monomials for each left and right column respectivewy.
   typedef std::vector<monomial> MonomialsType;
diff --git a/src/test/F4MatrixBuilder.cpp b/src/test/F4MatrixBuilder.cpp
new file mode 100755
index 0000000..f05e300
--- /dev/null
+++ b/src/test/F4MatrixBuilder.cpp
@@ -0,0 +1,139 @@
+#include "mathicgb/stdinc.h"
+
+#include "mathicgb/Poly.hpp"
+#include "mathicgb/PolyRing.hpp"
+#include "mathicgb/F4MatrixBuilder.hpp"
+#include "mathicgb/FreeModuleOrder.hpp"
+#include "mathicgb/Ideal.hpp"
+#include "mathicgb/PolyBasis.hpp"
+#include "mathicgb/io-util.hpp"
+#include <gtest/gtest.h>
+#include <memory>
+
+namespace {
+  // We need a struct to keep the ring and so on alive after
+  // construction - we cannot just return an object.
+  //
+  // @todo: This whole thing is fairly ridiculous - some kind of more
+  // general dependency injection mechanism might be nice here.
+  struct BuilderMaker {
+    BuilderMaker():
+      mRing(ringFromString("101 6 1\n1 1 1 1 1 1")),
+      mIdeal(*mRing),
+      mOrder(FreeModuleOrder::makeOrder(1, &mIdeal)),
+      mBasis(*mRing, *mOrder, DivisorLookup::makeFactory(*mRing, 1)->create(true, true)) {
+    }
+
+    const Poly& addBasisElement(const std::string& str) {
+      std::auto_ptr<Poly> p(new Poly(mRing.get()));
+      std::istringstream in(str);
+      p->parse(in);
+      mBasis.insert(p);
+      return mBasis.poly(mBasis.size() - 1);
+    }
+
+    F4MatrixBuilder& create() {
+      MATHICGB_ASSERT(mBuilder.get() == 0);
+      mBuilder.reset(new F4MatrixBuilder(mBasis));
+      return *mBuilder;
+    }
+
+    const PolyRing& ring() const {return *mRing;}
+     
+  private:
+    std::auto_ptr<PolyRing> mRing;
+    Ideal mIdeal;
+    std::auto_ptr<FreeModuleOrder> mOrder;
+    PolyBasis mBasis;
+    std::auto_ptr<F4MatrixBuilder> mBuilder;
+  };
+}
+
+TEST(F4MatrixBuilder, Empty) {
+  BuilderMaker maker;
+  F4MatrixBuilder& builder = maker.create();
+
+  QuadMatrix matrix;
+  builder.buildMatrixAndClear(matrix);
+  ASSERT_EQ(0, matrix.topLeft.rowCount());
+  ASSERT_EQ(0, matrix.bottomLeft.rowCount());
+  ASSERT_EQ(0, matrix.topLeft.colCount());
+  ASSERT_EQ(0, matrix.topRight.colCount());
+  ASSERT_EQ(0, matrix.leftColumnMonomials.size());
+  ASSERT_EQ(0, matrix.rightColumnMonomials.size());
+}
+
+TEST(F4MatrixBuilder, OneByOne) {
+  BuilderMaker maker;
+  const Poly& p = maker.addBasisElement("a");
+  F4MatrixBuilder& builder = maker.create();
+  builder.addRowToMatrix(p.getLeadMonomial(), p);
+  QuadMatrix qm;
+  builder.buildMatrixAndClear(qm);
+  const char* str = 
+    "Left columns: a2\n"
+    "Right columns:\n"
+    "0: 0#1              | 0:                 \n"
+    "                    |                    \n"
+    "matrix with no rows | matrix with no rows\n";
+  ASSERT_EQ(str, qm.toString());
+}
+
+TEST(F4MatrixBuilder, DirectReducers) {
+  BuilderMaker maker;
+  maker.addBasisElement("a6<0>"); // reducer ==, but won't be used as not added
+  maker.addBasisElement("a3b2<0>+a3c"); // reducer ==
+  maker.addBasisElement("c<0>"); // reducer divides
+  maker.addBasisElement("d2<0>"); // does not divide
+  F4MatrixBuilder& builder = maker.create();
+
+  Poly p1(&builder.ring());
+  { 
+    std::istringstream in("a3<0>+b2+c+d");
+    p1.parse(in);
+    builder.addRowToMatrix(p1.getLeadMonomial(), p1);
+  }
+
+  Poly p2(&builder.ring());
+  {
+    std::istringstream in("a3<0>+2b2+3c+4d");
+    p2.parse(in);
+    builder.addRowToMatrix(p2.getLeadMonomial(), p2);
+  }
+
+  QuadMatrix qm;
+  builder.buildMatrixAndClear(qm);
+
+  const char* str =
+    "Left columns: a6 a3b2 a3c\n"
+    "Right columns: a3d\n"
+    "0: 2#1         | 0:    \n"
+    "1: 1#1 2#1     | 1:    \n"
+    "2: 0#1 1#1 2#1 | 2: 0#1\n"
+    "               |       \n"
+    "0: 0#1 1#2 2#3 | 0: 0#4\n";
+  // This quest is currently fragile because of the possibility of
+  // reordering of the rows.
+  ASSERT_EQ(str, qm.toString());
+}
+
+TEST(F4MatrixBuilder, IteratedReducer) {
+  BuilderMaker maker;
+  const Poly& p1 = maker.addBasisElement("a4-a3");
+  const Poly& p2 = maker.addBasisElement("a-1");
+  F4MatrixBuilder& builder = maker.create();
+  builder.addRowToMatrix(p1.getLeadMonomial(), p2);
+  QuadMatrix qm;
+  builder.buildMatrixAndClear(qm);
+  const char* str = 
+    "Left columns: a5 a4 a3 a2 a\n"
+    "Right columns: 1\n"
+    "0: 0#1 1#100        | 0:                 \n"
+    "1: 1#1 2#100        | 1:                 \n"
+    "2: 2#1 3#100        | 2:                 \n"
+    "3: 3#1 4#100        | 3:                 \n"
+    "4: 4#1              | 4: 0#100           \n"
+    "                    |                    \n"
+    "matrix with no rows | matrix with no rows\n";
+  ASSERT_EQ(str, qm.toString());
+}
diff --git a/src/test/QuadMatrixBuilder.cpp b/src/test/QuadMatrixBuilder.cpp
index 726741b..17daa41 100755
--- a/src/test/QuadMatrixBuilder.cpp
+++ b/src/test/QuadMatrixBuilder.cpp
@@ -6,9 +6,16 @@
 #include "mathicgb/io-util.hpp"
 #include "mathicgb/FreeModuleOrder.hpp"
 #include "mathicgb/Ideal.hpp"
+#include "mathicgb/QuadMatrix.hpp"
 #include <gtest/gtest.h>
 
 namespace {
+  std::string monToStr(const PolyRing& ring, ConstMonomial a) {
+    std::ostringstream out;
+    ring.monomialDisplay(out, a, false, true);
+    return out.str();
+  }
+
   void createColumns(const char* left, const char* right, QuadMatrixBuilder& b)
   {
     const PolyRing& ring = b.ring();
@@ -197,3 +204,42 @@ TEST(QuadMatrixBuilder, SortColumns) {
     ASSERT_EQ(matrixStr3, b.toString());
   }
 }
+
+TEST(QuadMatrixBuilder, BuildAndClear) {
+  std::auto_ptr<PolyRing> ring(ringFromString("32003 6 1\n1 1 1 1 1 1"));
+  QuadMatrixBuilder b(*ring);
+  createColumns("a<1>+<0>", "b<0>+c<0>+bc<0>", b);
+
+  b.appendEntryTopLeft(1, 1);
+  b.appendEntryTopRight(2, 2);
+  b.rowDoneTopLeftAndRight();
+
+  b.appendEntryBottomLeft(1, 3);
+  b.appendEntryBottomRight(2, 4);
+  b.rowDoneBottomLeftAndRight();
+
+  QuadMatrix qm;
+  b.buildMatrixAndClear(qm);
+
+  // test that the matrix was really cleared
+  ASSERT_EQ(ring.get(), &b.ring()); // still same ring though
+  const char* matrixStr = 
+    "Left columns:\n"
+    "Right columns:\n"
+    "matrix with no rows | matrix with no rows\n"
+    "                    |                    \n"
+    "matrix with no rows | matrix with no rows\n";
+  ASSERT_EQ(matrixStr, b.toString());
+  ASSERT_EQ(0, b.leftColCount());
+  ASSERT_EQ(0, b.rightColCount());
+
+  // test that the quad matrix is right
+  ASSERT_EQ("0: 1#1\n", qm.topLeft.toString());
+  ASSERT_EQ("0: 2#2\n", qm.topRight.toString());
+  ASSERT_EQ("0: 1#3\n", qm.bottomLeft.toString());
+  ASSERT_EQ("0: 2#4\n", qm.bottomRight.toString());
+  ASSERT_EQ(2, qm.leftColumnMonomials.size());
+  ASSERT_EQ(3, qm.rightColumnMonomials.size());
+  ASSERT_EQ("a", monToStr(*ring, qm.leftColumnMonomials[0]));
+  ASSERT_EQ("b", monToStr(*ring, qm.rightColumnMonomials[0]));
+}
diff --git a/src/test/gb-test.cpp b/src/test/gb-test.cpp
index 627ec2a..3082b43 100755
--- a/src/test/gb-test.cpp
+++ b/src/test/gb-test.cpp
@@ -43,9 +43,6 @@ void testGB(int freeModuleOrder,
             std::string initialIdealStr,
             size_t nonSingularReductions)
 {
-  // todo: signatureBasis no longer does anything, rerun pict to get rid
-  // of that variable.
-  //
   // Put the contents of pict.out into allPairsTest as a string. This
   // works because pict.out does not have any commas and we do not
   // care about whitespace. pict.out contains a set of tests such that
@@ -53,116 +50,121 @@ void testGB(int freeModuleOrder,
   // pict.in for details.
 #define MATHICGB_ESCAPE_MULTILINE_STRING(str) #str
   char const allPairsTests[] = MATHICGB_ESCAPE_MULTILINE_STRING(
-spairQueue	reducerType	divLookup	monTable	signatureBasis	buchberger	postponeKoszul	useBaseDivisors	autoTailReduce	autoTopReduce	preferSparseReducers	useSingularCriterionEarly
-1	13	1	0	1	0	0	0	0	0	1	0
-1	18	2	2	0	0	1	1	0	0	0	1
-2	2	2	1	0	1	0	0	1	1	0	0
-2	18	1	1	1	0	0	1	0	0	1	1
-3	16	1	2	0	1	0	0	1	1	1	0
-0	13	2	0	1	0	1	1	0	0	0	1
-1	11	2	0	0	1	0	0	1	1	1	0
-1	17	2	1	0	1	0	0	1	0	1	0
-1	15	1	0	0	1	0	0	0	1	0	0
-0	21	1	1	0	1	0	0	1	1	1	0
-2	0	2	0	0	1	0	0	1	0	1	0
-1	24	1	1	1	0	1	1	0	0	1	0
-1	6	1	2	1	0	1	0	0	0	0	1
-2	16	2	1	1	0	1	1	0	0	0	1
-3	22	2	1	1	0	1	1	0	0	0	1
-2	8	1	2	0	0	1	1	0	0	1	1
-0	12	2	2	0	0	1	1	0	0	1	1
-0	17	1	0	1	0	1	1	0	0	0	1
-2	6	2	0	0	1	0	0	1	1	1	0
-0	9	1	0	1	0	0	0	0	0	1	1
-3	3	2	0	0	1	0	0	0	1	0	0
-3	10	1	1	0	1	0	0	1	0	0	0
-2	13	1	2	0	0	0	0	0	0	1	1
-2	19	1	0	0	0	1	0	0	0	0	1
-2	11	1	2	1	0	1	1	0	0	0	1
-3	21	2	2	1	0	1	1	0	0	0	1
-3	12	1	1	0	1	0	0	1	1	0	0
-3	0	1	1	1	0	1	1	0	0	0	1
-3	23	2	0	0	0	0	0	0	0	1	1
-3	24	2	2	0	0	0	0	0	0	0	1
-1	22	1	2	0	1	0	0	1	1	1	0
-2	9	2	2	0	1	0	0	1	1	0	0
-1	0	2	2	1	0	0	1	0	0	1	1
-1	21	2	0	0	1	0	0	0	0	1	0
-3	9	2	1	0	1	0	0	0	1	0	0
-3	6	1	1	0	0	0	1	0	0	1	0
-3	15	2	1	1	0	1	1	0	0	1	1
-2	7	1	2	0	0	1	0	0	0	0	0
-0	19	2	1	0	1	0	0	1	1	1	0
-0	23	1	1	0	1	0	0	1	1	0	0
-2	12	2	0	1	0	1	1	0	0	1	1
-2	14	2	2	0	1	0	0	1	0	1	0
-0	5	2	0	0	0	1	1	0	0	0	0
-3	11	1	1	0	0	1	0	0	0	0	1
-2	23	2	2	1	0	1	1	0	0	0	0
-3	17	2	2	0	1	0	0	0	1	0	0
-1	2	1	2	1	0	1	1	0	0	1	1
-3	18	1	0	0	1	0	0	1	1	0	0
-0	20	1	2	0	1	0	0	1	0	0	0
-3	20	2	1	1	0	1	1	0	0	1	1
-0	15	1	2	0	1	0	0	1	0	0	0
-0	0	1	1	0	1	0	0	1	1	1	0
-0	7	2	0	1	0	0	1	0	0	1	1
-1	14	1	0	1	0	1	1	0	0	0	1
-0	16	1	0	0	1	0	0	1	0	1	0
-2	22	1	0	0	0	0	1	0	0	1	1
-1	16	1	2	1	0	0	1	0	0	0	1
-3	14	1	1	1	0	1	0	0	0	1	1
-0	4	2	1	0	0	1	0	0	0	1	1
-0	6	2	1	1	0	1	1	0	0	1	1
-2	5	1	2	1	0	0	0	0	0	1	1
-2	15	1	2	1	0	0	1	0	0	1	1
-1	9	2	2	0	0	1	1	0	0	0	1
-1	12	2	1	1	0	0	0	0	0	0	1
-0	8	2	1	0	1	0	0	1	1	0	0
-3	4	1	0	0	1	0	0	1	1	0	0
-1	5	2	1	0	1	0	0	1	1	0	0
-0	3	1	2	1	0	1	1	0	0	1	1
-0	2	1	0	0	0	1	1	0	0	0	0
-1	10	2	0	1	0	1	1	0	0	1	1
-2	24	2	0	0	1	0	0	1	1	0	0
-0	22	2	0	0	0	1	1	0	0	1	1
-3	19	2	2	1	0	0	1	0	0	1	0
-3	7	2	1	0	1	0	0	1	1	1	0
-3	8	1	0	0	1	0	0	1	1	1	0
-2	17	2	0	0	0	1	1	0	0	1	1
-1	8	2	0	0	1	0	0	0	1	0	0
-2	3	1	1	0	0	1	1	0	0	1	1
-3	5	1	1	0	0	1	0	0	0	1	1
-0	24	1	2	1	0	1	1	0	0	1	1
-0	18	1	2	0	1	0	0	1	1	1	0
-1	7	2	2	1	0	1	0	0	0	0	1
-2	4	1	2	0	1	0	0	1	0	1	0
-1	4	2	1	1	0	0	1	0	0	1	1
-0	14	1	1	0	1	0	0	0	1	0	0
-3	1	1	2	0	1	0	0	1	1	1	0
-2	20	2	0	1	0	0	1	0	0	1	1
-0	10	2	2	0	0	1	1	0	0	1	1
-3	13	1	1	0	1	0	0	1	1	0	0
-2	21	2	2	0	1	0	0	0	1	0	0
-3	2	1	2	0	1	0	0	1	0	1	0
-0	11	2	2	1	0	1	1	0	0	0	1
-1	19	2	2	0	0	0	0	0	0	0	1
-1	3	2	0	0	1	0	0	1	1	1	0
-1	1	2	1	1	0	1	1	0	0	0	1
-2	10	1	0	1	0	0	0	0	0	0	1
-1	20	1	1	1	0	1	1	0	0	1	1
-0	1	1	0	0	0	0	0	0	0	1	1
-0	20	1	2	0	1	0	0	0	1	1	0
-2	1	1	1	0	1	0	0	1	1	0	0
-1	23	2	0	0	0	0	0	0	0	1	1
-0	10	2	1	0	1	0	0	0	1	1	0
-3	8	1	0	1	0	1	1	0	0	0	1
+spairQueue	reducerType	divLookup	monTable	buchberger	postponeKoszul	useBaseDivisors	autoTailReduce	autoTopReduce	preferSparseReducers	useSingularCriterionEarly
+2	12	1	1	0	0	0	0	0	1	0
+1	6	2	2	0	1	1	0	0	0	1
+0	6	2	0	1	0	0	1	1	0	0
+1	7	1	2	1	0	0	1	1	1	0
+0	15	1	0	0	1	1	0	0	1	1
+2	8	2	1	0	0	1	0	0	0	1
+2	4	1	1	1	0	0	0	1	0	0
+3	19	2	1	1	0	0	1	0	1	0
+1	11	1	1	1	0	0	1	0	1	0
+0	14	1	1	1	0	0	1	0	0	0
+1	9	2	0	1	0	0	1	1	0	0
+1	15	2	1	1	0	0	1	1	0	0
+2	22	1	0	1	0	0	1	0	1	0
+3	14	1	0	0	1	1	0	0	1	1
+2	6	1	1	1	0	0	1	1	1	0
+0	10	2	2	1	0	0	0	1	1	0
+2	7	2	1	0	1	0	0	0	0	1
+2	14	2	2	1	0	0	1	1	1	0
+3	20	1	2	1	0	0	0	1	0	0
+0	8	1	2	1	0	0	1	1	1	0
+0	1	1	1	0	1	1	0	0	1	0
+3	22	2	1	0	1	1	0	0	0	1
+1	10	1	1	0	1	1	0	0	0	1
+2	11	2	0	0	1	1	0	0	0	1
+0	25	2	0	1	0	0	0	1	0	0
+2	15	1	2	0	0	1	0	0	0	1
+2	21	2	0	0	1	0	0	0	1	1
+3	2	2	1	0	1	0	0	0	0	0
+2	5	1	0	0	1	1	0	0	0	1
+1	12	2	0	0	1	1	0	0	0	1
+0	19	1	2	0	1	1	0	0	0	1
+3	17	1	0	0	1	1	0	0	0	0
+1	14	2	2	0	0	0	0	0	1	1
+3	1	2	0	0	0	0	0	0	0	1
+2	0	1	1	1	0	0	1	0	1	0
+2	20	2	0	0	1	1	0	0	1	1
+0	23	1	2	1	0	0	1	0	1	0
+0	0	2	0	0	1	1	0	0	0	1
+2	2	1	2	0	0	1	0	0	1	1
+2	16	2	0	1	0	0	0	1	0	0
+0	20	2	1	1	0	0	1	0	0	0
+1	3	2	2	0	0	1	0	0	1	1
+0	24	2	0	1	0	0	1	0	0	0
+3	7	2	0	0	1	1	0	0	1	1
+1	0	1	2	0	1	0	0	0	0	1
+2	23	2	1	0	1	1	0	0	0	1
+1	18	2	1	0	1	0	0	0	1	1
+1	20	1	1	0	0	0	0	0	0	1
+2	25	1	1	0	1	1	0	0	1	1
+3	9	1	1	0	1	1	0	0	1	1
+1	23	2	0	0	1	1	0	0	0	1
+2	17	2	2	0	0	0	0	0	1	1
+0	21	1	2	1	0	0	1	1	0	0
+3	3	1	1	1	0	0	1	1	0	0
+2	1	1	2	1	0	0	1	1	0	0
+1	5	2	2	1	0	0	1	1	1	0
+3	21	1	1	1	0	0	1	0	1	0
+3	6	1	0	0	0	0	0	0	1	1
+0	9	2	2	1	0	0	0	1	1	0
+3	11	2	2	0	0	0	0	0	1	1
+3	10	1	0	1	0	0	1	0	1	0
+2	19	1	0	1	0	0	1	1	1	0
+0	12	2	2	1	0	0	1	1	1	0
+0	2	2	0	0	1	0	0	0	0	1
+1	25	1	2	1	0	0	1	1	0	0
+1	16	1	2	0	1	1	0	0	1	1
+1	4	2	2	0	1	1	0	0	1	1
+3	25	1	2	0	1	1	0	0	0	1
+1	8	1	0	1	0	0	1	0	0	0
+2	18	1	0	1	0	0	1	1	0	0
+0	4	2	0	1	0	0	1	1	0	0
+0	18	2	2	0	1	1	0	0	1	1
+1	17	2	1	0	0	1	0	0	1	1
+1	24	1	2	0	1	1	0	0	1	1
+3	24	2	1	1	0	0	0	1	0	0
+1	19	1	2	0	0	1	0	0	0	1
+1	21	2	2	0	1	1	0	0	1	1
+3	16	2	1	0	1	0	0	0	1	1
+0	22	2	2	0	1	0	0	0	1	1
+3	0	2	2	0	1	1	0	0	0	1
+2	9	2	2	1	0	0	1	0	1	0
+3	18	1	1	0	1	0	0	0	1	1
+3	15	1	2	0	1	0	0	0	0	1
+1	1	1	1	0	1	0	0	0	1	1
+2	24	1	1	0	0	1	0	0	0	1
+2	3	2	0	0	1	1	0	0	0	1
+0	11	2	2	1	0	0	1	1	1	0
+3	13	2	1	1	0	0	1	0	0	0
+3	12	1	1	1	0	0	1	1	1	0
+0	5	2	1	1	0	0	1	0	0	0
+1	22	1	0	1	0	0	0	1	0	0
+2	13	1	2	0	1	1	0	0	1	1
+0	16	2	0	0	0	0	0	0	0	1
+0	17	2	2	0	0	0	0	0	0	1
+1	2	1	1	1	0	0	1	1	0	0
+3	23	2	0	0	1	1	0	0	0	1
+0	7	1	0	0	1	0	0	0	1	1
+1	13	1	0	0	1	1	0	0	0	1
+2	10	1	0	0	1	0	0	0	1	1
+0	13	1	0	1	0	0	0	1	0	0
+3	4	1	0	0	0	0	0	0	1	1
+2	23	1	0	1	0	0	1	1	1	0
+3	5	1	0	0	1	0	0	0	0	1
+0	3	1	2	0	1	0	0	0	1	1
+3	16	1	1	1	0	0	1	1	0	0
+0	17	1	0	1	0	0	1	1	1	0
+3	8	1	2	0	1	1	0	0	0	1
+2	0	2	0	1	0	0	0	1	0	0
 );
   std::istringstream tests(allPairsTests);
   // skip the initial line with the parameter names.
   {
       char const* params[] = {
-        "spairQueue", "reducerType", "divLookup", "monTable", "signatureBasis",
+        "spairQueue", "reducerType", "divLookup", "monTable",
         "buchberger", "postponeKoszul", "useBaseDivisors", "autoTailReduce",
         "autoTopReduce", "preferSparseReducers", "useSingularCriterionEarly"};
 
@@ -202,10 +204,6 @@ spairQueue	reducerType	divLookup	monTable	signatureBasis	buchberger	postponeKosz
     tests >> monTable;
     MATHICGB_ASSERT(0 <= monTable && monTable <= 2);
     
-    int signatureBasis;
-    tests >> signatureBasis;
-    MATHICGB_ASSERT(0 <= signatureBasis && signatureBasis <= 1);
-
     int buchberger;
     tests >> buchberger;
     MATHICGB_ASSERT(0 <= buchberger && buchberger <= 1);
@@ -242,7 +240,6 @@ spairQueue	reducerType	divLookup	monTable	signatureBasis	buchberger	postponeKosz
     MATHICGB_ASSERT(buchberger || !autoTailReduce);
     MATHICGB_ASSERT(!buchberger || !postponeKoszul);
     MATHICGB_ASSERT(!buchberger || !useBaseDivisors);
-    MATHICGB_ASSERT(!buchberger || !signatureBasis);
     MATHICGB_ASSERT(!buchberger || !useSingularCriterionEarly);
 
     // check that we have a valid reducer type
diff --git a/src/test/pict.in b/src/test/pict.in
index 09d5bd9..e21ca1b 100755
--- a/src/test/pict.in
+++ b/src/test/pict.in
@@ -12,17 +12,20 @@
 # You will need to run this program on Windows. It is a closed source
 # utility. There are open sources alternatives but they are not as good.
 #
-# To update the test in gb-test.cpp, update this file, run pict and
-# place the output into the string allPairsTest in gb-test.cpp.
+# To update the test in gb-test.cpp, do
+#
+#   pick pict.in > pict.out
+#
+# Then place the entire contents of pict.out (including newlines) into
+# the string allPairsTest in gb-test.cpp.
 
 ##############################################################
 # This is the PICT model specifying all parameters and their values
 #
 spairQueue: 0,1,2,3
-reducerType: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
+reducerType: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25
 divLookup: 1, 2
 monTable: 0, 1, 2
-signatureBasis: 0, 1
 buchberger: 0, 1
 postponeKoszul: 0, 1
 useBaseDivisors: 0, 1
@@ -48,5 +51,4 @@ IF [buchberger] = 0 THEN
 IF [buchberger] = 1 THEN
   [postponeKoszul] = 0 AND
   [useBaseDivisors] = 0 AND
-  [signatureBasis] = 0 AND
   [usesingularCriterionEarly] = 0;

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