[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