[mathicgb] 29/393: Added an F4MatrixBuilder and an F4Reducer - they do not work yet.

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 f6980a1e6448ce8e2957c077082fb26a83998134
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Wed Sep 26 18:46:03 2012 +0200

    Added an F4MatrixBuilder and an F4Reducer - they do not work yet.
    
    The new code in this commit compiles but if you specify the option to
    use the F4Reducer (reducer #25) you get a segmentation fault for
    classically reducing an S-pair. The other F4 reducer methods work only
    because they currently are actually just letting another reducer do
    the work. Next up: testing and fixing.
---
 Makefile.am                      |   4 +-
 src/mathicgb/F4MatrixBuilder.cpp |   2 +
 src/mathicgb/F4MatrixBuilder.hpp | 182 +++++++++++++++++++++++++++++++++++++++
 src/mathicgb/F4Reducer.cpp       |  69 +++++++++++++++
 src/mathicgb/F4Reducer.hpp       |  39 +++++++++
 src/mathicgb/Reducer.cpp         |  12 ++-
 src/mathicgb/Reducer.hpp         |   4 +-
 7 files changed, 309 insertions(+), 3 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 573ae1c..b1b1a7b 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -56,7 +56,9 @@ libmathicgb_la_SOURCES = src/mathicgb/BjarkeGeobucket2.cpp				\
   src/mathicgb/SigSPairQueue.cpp src/mathicgb/SparseMatrix.hpp			\
   src/mathicgb/SparseMatrix.cpp src/mathicgb/QuadMatrixBuilder.hpp		\
   src/mathicgb/QuadMatrixBuilder.cpp src/mathicgb/TypicalReducer.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
 
 # When making a distribution file, Automake knows to include all files
 # that are necessary to build the project. EXTRA_DIST specifies files
diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
new file mode 100755
index 0000000..4394c8b
--- /dev/null
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -0,0 +1,2 @@
+#include "stdinc.h"
+#include "F4MatrixBuilder.hpp"
diff --git a/src/mathicgb/F4MatrixBuilder.hpp b/src/mathicgb/F4MatrixBuilder.hpp
new file mode 100755
index 0000000..02b9f22
--- /dev/null
+++ b/src/mathicgb/F4MatrixBuilder.hpp
@@ -0,0 +1,182 @@
+#ifndef F4_MATRIX_BUILDER_GUARD
+#define F4_MATRIX_BUILDER_GUARD
+
+#include "QuadMatrixBuilder.hpp"
+#include "Poly.hpp"
+#include "PolyRing.hpp"
+#include "PolyBasis.hpp"
+#include <vector>
+
+/** Class for constructing an F4 matrix. This class is reponsible for
+  figuring out what matrix to build and then it uses QuadMatrixBuilder
+  to create that matrix.
+
+  @todo: this class does not offer exception guarantees. It's just not
+  very workable without an RAII monomial handle, so add one of those
+  before fixing this. */
+class F4MatrixBuilder {
+private:
+  typedef QuadMatrixBuilder::ColIndex ColIndex;
+  typedef QuadMatrixBuilder::LeftRightColIndex LeftRightColIndex;
+
+public:
+  F4MatrixBuilder(const PolyBasis& basis):
+    mBasis(basis), mBuilder(basis.ring()) {}
+
+  /** 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);
+  }
+
+  /** 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);
+  }
+
+  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);
+  }
+
+  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);
+  }
+
+  /// Represents the task of adding a row representing poly*multiple.
+  struct RowTask {
+    bool useAsReducer; // if true: put in top part of matrix
+    const Poly* poly;
+    monomial multiple;
+  };
+  std::vector<RowTask> mTodo;
+  const PolyBasis& mBasis;
+  QuadMatrixBuilder mBuilder;
+};
+
+#endif
diff --git a/src/mathicgb/F4Reducer.cpp b/src/mathicgb/F4Reducer.cpp
new file mode 100755
index 0000000..2a7fc3e
--- /dev/null
+++ b/src/mathicgb/F4Reducer.cpp
@@ -0,0 +1,69 @@
+#include "stdinc.h"
+#include "F4Reducer.hpp"
+
+#include "F4MatrixBuilder.hpp"
+
+F4Reducer::F4Reducer(const PolyRing& ring, std::auto_ptr<Reducer> fallback):
+  mFallback(fallback), mRing(ring) {
+}
+
+std::auto_ptr<Poly> F4Reducer::classicReduce
+(const Poly& poly, const PolyBasis& basis) {
+  std::auto_ptr<Poly> p;
+  p = mFallback->classicReduce(poly, basis);
+  mSigStats = mFallback->sigStats();
+  mClassicStats = mFallback->classicStats();
+  return p;
+}
+
+std::auto_ptr<Poly> F4Reducer::classicTailReduce
+(const Poly& poly, const PolyBasis& basis) {
+  std::auto_ptr<Poly> p;
+  p = mFallback->classicTailReduce(poly, basis);
+  mSigStats = mFallback->sigStats();
+  mClassicStats = mFallback->classicStats();
+  return p;
+}
+
+std::auto_ptr<Poly> F4Reducer::classicReduceSPoly
+(const Poly& a, const Poly& b, const PolyBasis& basis) {
+  std::auto_ptr<Poly> p;
+  {
+    p = mFallback->classicReduceSPoly(a, b, basis);
+    mSigStats = mFallback->sigStats();
+    mClassicStats = mFallback->classicStats();
+  }
+
+  SparseMatrix topLeft;
+  SparseMatrix topRight;
+  SparseMatrix bottomLeft;
+  SparseMatrix bottomRight;
+  std::vector<monomial> monomialsOfRightColumns;
+  {
+    F4MatrixBuilder builder(basis);
+    builder.addTwoRowsForSPairToMatrix(a, b);
+    builder.buildMatricesAndClear
+      (topLeft, topRight, bottomLeft, bottomRight, monomialsOfRightColumns);
+  }
+
+  return p;
+}
+
+Poly* F4Reducer::regularReduce
+(const_monomial sig,
+ const_monomial multiple,
+ size_t basisElement,
+ const GroebnerBasis& basis) {
+  Poly* p = mFallback->regularReduce(sig, multiple, basisElement, basis);
+  mSigStats = mFallback->sigStats();
+  mClassicStats = mFallback->classicStats();
+  return p;
+}
+
+std::string F4Reducer::description() const {
+  return "F4 reducer";
+}
+
+size_t F4Reducer::getMemoryUse() const {
+  return 0;
+}
diff --git a/src/mathicgb/F4Reducer.hpp b/src/mathicgb/F4Reducer.hpp
new file mode 100755
index 0000000..91315d9
--- /dev/null
+++ b/src/mathicgb/F4Reducer.hpp
@@ -0,0 +1,39 @@
+#ifndef MATHICGB_F4_REDUCER_GUARD
+#define MATHICGB_F4_REDUCER_GUARD
+
+#include "Reducer.hpp"
+#include "PolyRing.hpp"
+
+class F4Reducer : public Reducer {
+public:
+  F4Reducer(const PolyRing& ring, std::auto_ptr<Reducer> fallback);
+
+  virtual std::auto_ptr<Poly> classicReduce
+  (const Poly& poly, const PolyBasis& basis);
+
+  virtual std::auto_ptr<Poly> classicTailReduce
+  (const Poly& poly, const PolyBasis& basis);
+
+  virtual std::auto_ptr<Poly> classicReduceSPoly
+  (const Poly& a, const Poly& b, const PolyBasis& basis);
+
+  virtual Poly* regularReduce(
+    const_monomial sig,
+    const_monomial multiple,
+    size_t basisElement,
+    const GroebnerBasis& basis);
+
+  virtual std::string description() const;
+  virtual size_t getMemoryUse() const;
+
+private:
+  std::auto_ptr<Reducer> mFallback;
+  const PolyRing& mRing;
+};
+
+#endif
+
+// Local Variables:
+// compile-command: "make -C .. "
+// indent-tabs-mode: nil
+// End:
diff --git a/src/mathicgb/Reducer.cpp b/src/mathicgb/Reducer.cpp
index 3ceb388..e2d6f2d 100755
--- a/src/mathicgb/Reducer.cpp
+++ b/src/mathicgb/Reducer.cpp
@@ -13,8 +13,8 @@
 #include "ReducerNoDedup.hpp"
 #include "ReducerDedup.hpp"
 #include "ReducerHash.hpp"
-
 #include "ReducerHashPack.hpp"
+#include "F4Reducer.hpp"
 
 #include "GroebnerBasis.hpp"
 #include <iostream>
@@ -108,6 +108,12 @@ std::auto_ptr<Reducer> Reducer::makeReducerNullOnUnknown(
   case Reducer_Geobucket_Hashed_Packed:
     return std::auto_ptr<Reducer>(new ReducerHashPack<mic::Geobucket>(ring));
 
+  case Reducer_F4:
+    {
+      std::auto_ptr<Reducer> fallback = makeReducer(Reducer_BjarkeGeo, ring);
+      return std::auto_ptr<Reducer>(new F4Reducer(ring, fallback));
+    }
+
   default:
     break;
   };
@@ -146,6 +152,8 @@ Reducer::ReducerType Reducer::reducerType(int typ)
   case 23: return Reducer_Geobucket_Dedup_Packed;
   case 24: return Reducer_Geobucket_Hashed_Packed;
 
+  case 25: return Reducer_F4;
+
   default: return Reducer_PolyHeap;
   }
 }
@@ -181,6 +189,8 @@ void Reducer::displayReducerTypes(std::ostream &o)
   o << "  22   Geobucket.NoDedup.Packed" << std::endl;
   o << "  23   Geobucket.Dedup.Packed" << std::endl;
   o << "  24   Geobucket.Hashed.Packed" << std::endl;
+
+  o << "  25   F4 reducer" << std::endl;
 }
 
 // Todo: can't this be machine generated?
diff --git a/src/mathicgb/Reducer.hpp b/src/mathicgb/Reducer.hpp
index 2376adc..589738f 100755
--- a/src/mathicgb/Reducer.hpp
+++ b/src/mathicgb/Reducer.hpp
@@ -76,7 +76,9 @@ public:
     Reducer_Geobucket_Hashed,
     Reducer_Geobucket_NoDedup_Packed,
     Reducer_Geobucket_Dedup_Packed,
-    Reducer_Geobucket_Hashed_Packed
+    Reducer_Geobucket_Hashed_Packed,
+
+    Reducer_F4
   };
 
   static std::auto_ptr<Reducer> makeReducer

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