[mathicgb] 307/393: Adding new external-to-MonoMonoid IO class MathicIO along with tests.
Doug Torrance
dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:26 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 613868a7c2315aefadfcf81c685edee0db2a5476
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date: Sun May 5 14:48:27 2013 +0200
Adding new external-to-MonoMonoid IO class MathicIO along with tests.
---
Makefile.am | 114 +++++-----
src/mathicgb/Basis.cpp | 4 +-
src/mathicgb/MathicIO.cpp | 3 +
src/mathicgb/MathicIO.hpp | 489 +++++++++++++++++++++++++++++++++++++++++
src/mathicgb/MonoMonoid.hpp | 42 +++-
src/mathicgb/MonoOrder.hpp | 24 +-
src/mathicgb/MonoProcessor.hpp | 13 +-
src/mathicgb/PrimeField.hpp | 3 +
src/mathicgb/Scanner.cpp | 3 +-
src/test/MathicIO.cpp | 171 ++++++++++++++
10 files changed, 798 insertions(+), 68 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 46ca9be..d913337 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,59 +13,61 @@ libmathicgb_la_LIBADD= $(DEPS_LIBS)
# the sources that are built to make libmathicgb. Listing the headers in
# sources ensure that those files are included in distributions.
-libmathicgb_la_SOURCES = src/mathicgb/BjarkeGeobucket2.cpp \
+libmathicgb_la_SOURCES = src/mathicgb/BjarkeGeobucket2.cpp \
src/mathicgb/BjarkeGeobucket2.hpp src/mathicgb/BjarkeGeobucket.cpp \
- src/mathicgb/BjarkeGeobucket.hpp src/mathicgb/BuchbergerAlg.cpp \
- src/mathicgb/BuchbergerAlg.hpp src/mathicgb/ChainedHashTable.cpp \
- src/mathicgb/ChainedHashTable.hpp src/mathicgb/DivisorLookup.hpp \
- src/mathicgb/DivisorLookup.cpp src/mathicgb/DivLookup.hpp \
- src/mathicgb/FreeModuleOrder.cpp src/mathicgb/FreeModuleOrder.hpp \
- src/mathicgb/GroebnerBasis.cpp src/mathicgb/GroebnerBasis.hpp \
- src/mathicgb/HashTourReducer.cpp src/mathicgb/HashTourReducer.hpp \
- src/mathicgb/Basis.cpp src/mathicgb/Basis.hpp \
- src/mathicgb/io-util.cpp src/mathicgb/io-util.hpp \
- src/mathicgb/KoszulQueue.cpp src/mathicgb/KoszulQueue.hpp \
+ src/mathicgb/BjarkeGeobucket.hpp src/mathicgb/BuchbergerAlg.cpp \
+ src/mathicgb/BuchbergerAlg.hpp src/mathicgb/ChainedHashTable.cpp \
+ src/mathicgb/ChainedHashTable.hpp src/mathicgb/DivisorLookup.hpp \
+ src/mathicgb/DivisorLookup.cpp src/mathicgb/DivLookup.hpp \
+ src/mathicgb/FreeModuleOrder.cpp src/mathicgb/FreeModuleOrder.hpp \
+ src/mathicgb/GroebnerBasis.cpp src/mathicgb/GroebnerBasis.hpp \
+ src/mathicgb/HashTourReducer.cpp src/mathicgb/HashTourReducer.hpp \
+ src/mathicgb/Basis.cpp src/mathicgb/Basis.hpp \
+ src/mathicgb/io-util.cpp src/mathicgb/io-util.hpp \
+ src/mathicgb/KoszulQueue.cpp src/mathicgb/KoszulQueue.hpp \
src/mathicgb/MonomialHashTable.hpp src/mathicgb/MonTableDivList.hpp \
- src/mathicgb/MonTableKDTree.hpp src/mathicgb/MonTableNaive.cpp \
- src/mathicgb/MonTableNaive.hpp src/mathicgb/MTArray.cpp \
- src/mathicgb/MTArray.hpp src/mathicgb/PairTriangle.cpp \
- src/mathicgb/PairTriangle.hpp src/mathicgb/Poly.cpp \
- src/mathicgb/Poly.hpp src/mathicgb/PolyBasis.cpp \
- src/mathicgb/PolyBasis.hpp src/mathicgb/PolyGeoBucket.cpp \
- src/mathicgb/PolyGeoBucket.hpp src/mathicgb/PolyHashReducer.cpp \
- src/mathicgb/PolyHashReducer.hpp src/mathicgb/PolyHashTable.cpp \
- src/mathicgb/PolyHashTable.hpp src/mathicgb/PolyHeap.cpp \
- src/mathicgb/PolyHeap.hpp src/mathicgb/PolyReducer.cpp \
- src/mathicgb/PolyReducer.hpp src/mathicgb/PolyRing.cpp \
- src/mathicgb/PolyRing.hpp src/mathicgb/Reducer.cpp \
- src/mathicgb/Reducer.hpp src/mathicgb/ReducerDedup.hpp \
- src/mathicgb/ReducerHash.hpp src/mathicgb/ReducerHashPack.hpp \
- src/mathicgb/ReducerHelper.hpp src/mathicgb/ReducerNoDedup.hpp \
- src/mathicgb/ReducerPack.hpp src/mathicgb/ReducerPackDedup.hpp \
- src/mathicgb/SignatureGB.cpp src/mathicgb/SignatureGB.hpp \
- src/mathicgb/SigSPairs.cpp src/mathicgb/SigSPairs.hpp \
- src/mathicgb/SPairs.cpp src/mathicgb/SPairs.hpp \
- src/mathicgb/stdinc.h src/mathicgb/TournamentReducer.cpp \
- src/mathicgb/TournamentReducer.hpp src/mathicgb/SigSPairQueue.hpp \
- src/mathicgb/SigSPairQueue.cpp src/mathicgb/SparseMatrix.hpp \
- src/mathicgb/SparseMatrix.cpp src/mathicgb/QuadMatrixBuilder.hpp \
+ src/mathicgb/MonTableKDTree.hpp src/mathicgb/MonTableNaive.cpp \
+ src/mathicgb/MonTableNaive.hpp src/mathicgb/MTArray.cpp \
+ src/mathicgb/MTArray.hpp src/mathicgb/PairTriangle.cpp \
+ src/mathicgb/PairTriangle.hpp src/mathicgb/Poly.cpp \
+ src/mathicgb/Poly.hpp src/mathicgb/PolyBasis.cpp \
+ src/mathicgb/PolyBasis.hpp src/mathicgb/PolyGeoBucket.cpp \
+ src/mathicgb/PolyGeoBucket.hpp src/mathicgb/PolyHashReducer.cpp \
+ src/mathicgb/PolyHashReducer.hpp src/mathicgb/PolyHashTable.cpp \
+ src/mathicgb/PolyHashTable.hpp src/mathicgb/PolyHeap.cpp \
+ src/mathicgb/PolyHeap.hpp src/mathicgb/PolyReducer.cpp \
+ src/mathicgb/PolyReducer.hpp src/mathicgb/PolyRing.cpp \
+ src/mathicgb/PolyRing.hpp src/mathicgb/Reducer.cpp \
+ src/mathicgb/Reducer.hpp src/mathicgb/ReducerDedup.hpp \
+ src/mathicgb/ReducerHash.hpp src/mathicgb/ReducerHashPack.hpp \
+ src/mathicgb/ReducerHelper.hpp src/mathicgb/ReducerNoDedup.hpp \
+ src/mathicgb/ReducerPack.hpp src/mathicgb/ReducerPackDedup.hpp \
+ src/mathicgb/SignatureGB.cpp src/mathicgb/SignatureGB.hpp \
+ src/mathicgb/SigSPairs.cpp src/mathicgb/SigSPairs.hpp \
+ src/mathicgb/SPairs.cpp src/mathicgb/SPairs.hpp \
+ src/mathicgb/stdinc.h src/mathicgb/TournamentReducer.cpp \
+ src/mathicgb/TournamentReducer.hpp src/mathicgb/SigSPairQueue.hpp \
+ 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.hpp src/mathicgb/F4Reducer.hpp \
- src/mathicgb/F4Reducer.cpp src/mathicgb/F4MatrixBuilder.hpp \
- src/mathicgb/F4MatrixBuilder.cpp src/mathicgb/QuadMatrix.hpp \
- src/mathicgb/QuadMatrix.cpp src/mathicgb/F4MatrixReducer.cpp \
- src/mathicgb/F4MatrixReducer.hpp src/mathicgb/MonomialMap.hpp \
- src/mathicgb/RawVector.hpp src/mathicgb/Atomic.hpp \
- src/mathicgb/FixedSizeMonomialMap.hpp src/mathicgb/CFile.hpp \
- src/mathicgb/CFile.cpp src/mathicgb/LogDomain.hpp \
- src/mathicgb/LogDomain.cpp src/mathicgb/LogDomainSet.hpp \
+ src/mathicgb/TypicalReducer.hpp src/mathicgb/F4Reducer.hpp \
+ src/mathicgb/F4Reducer.cpp src/mathicgb/F4MatrixBuilder.hpp \
+ src/mathicgb/F4MatrixBuilder.cpp src/mathicgb/QuadMatrix.hpp \
+ src/mathicgb/QuadMatrix.cpp src/mathicgb/F4MatrixReducer.cpp \
+ src/mathicgb/F4MatrixReducer.hpp src/mathicgb/MonomialMap.hpp \
+ src/mathicgb/RawVector.hpp src/mathicgb/Atomic.hpp \
+ src/mathicgb/FixedSizeMonomialMap.hpp src/mathicgb/CFile.hpp \
+ src/mathicgb/CFile.cpp src/mathicgb/LogDomain.hpp \
+ src/mathicgb/LogDomain.cpp src/mathicgb/LogDomainSet.hpp \
src/mathicgb/F4MatrixBuilder2.hpp src/mathicgb/F4MatrixBuilder2.cpp \
- src/mathicgb/LogDomainSet.cpp src/mathicgb/F4ProtoMatrix.hpp \
- src/mathicgb/F4ProtoMatrix.cpp src/mathicgb/F4MatrixProject.hpp \
- src/mathicgb/F4MatrixProjection.cpp src/mathicgb/ScopeExit.hpp \
- src/mathicgb.cpp src/mathicgb.h src/mathicgb/mtbb.hpp \
- src/mathicgb/PrimeField.hpp src/mathicgb/MonoMonoid.hpp \
- src/mathicgb/MonoProcessor.hpp src/mathicgb/MonoOrder.hpp
+ src/mathicgb/LogDomainSet.cpp src/mathicgb/F4ProtoMatrix.hpp \
+ src/mathicgb/F4ProtoMatrix.cpp src/mathicgb/F4MatrixProject.hpp \
+ src/mathicgb/F4MatrixProjection.cpp src/mathicgb/ScopeExit.hpp \
+ src/mathicgb.cpp src/mathicgb.h src/mathicgb/mtbb.hpp \
+ src/mathicgb/PrimeField.hpp src/mathicgb/MonoMonoid.hpp \
+ src/mathicgb/MonoProcessor.hpp src/mathicgb/MonoOrder.hpp \
+ src/mathicgb/Scanner.hpp src/mathicgb/Scanner.cpp \
+ src/mathicgb/Unchar.hpp
# The headers that libmathicgb installs.
@@ -103,12 +105,14 @@ check_PROGRAMS=$(TESTS)
unittest_LDADD = $(DEPS_LIBS) $(top_builddir)/libmathicgb.la
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/F4MatrixBuilder.cpp src/test/F4MatrixReducer.cpp \
- src/test/mathicgb.cpp src/test/PrimeField.cpp src/test/MonoMonoid.cpp
+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/F4MatrixBuilder.cpp \
+ src/test/F4MatrixReducer.cpp src/test/mathicgb.cpp \
+ src/test/PrimeField.cpp src/test/MonoMonoid.cpp \
+ src/test/Scanner.cpp src/test/MathicIO.cpp
else
diff --git a/src/mathicgb/Basis.cpp b/src/mathicgb/Basis.cpp
index 0e3665c..7b1048e 100755
--- a/src/mathicgb/Basis.cpp
+++ b/src/mathicgb/Basis.cpp
@@ -48,8 +48,8 @@ auto Basis::parse(std::istream& in) -> Parsed
delete r.first;
auto basis = make_unique<Basis>(*ring);
- auto processor = make_unique<MonoProcessor<Monoid>>(ring->monoid());
- processor->setComponentsAscendingDesired(r.second.first);
+ auto processor =
+ make_unique<MonoProcessor<Monoid>>(ring->monoid(), r.second.first, false);
size_t polyCount;
in >> polyCount;
diff --git a/src/mathicgb/MathicIO.cpp b/src/mathicgb/MathicIO.cpp
new file mode 100755
index 0000000..76b8486
--- /dev/null
+++ b/src/mathicgb/MathicIO.cpp
@@ -0,0 +1,3 @@
+#include "stdinc.h"
+#include "MathicIO.hpp"
+
diff --git a/src/mathicgb/MathicIO.hpp b/src/mathicgb/MathicIO.hpp
new file mode 100755
index 0000000..ba57efd
--- /dev/null
+++ b/src/mathicgb/MathicIO.hpp
@@ -0,0 +1,489 @@
+#ifndef MATHICGB_MATHIC_IO_GUARD
+#define MATHICGB_MATHIC_IO_GUARD
+
+#include "Scanner.hpp"
+#include "PolyRing.hpp"
+#include "MonoProcessor.hpp"
+#include <ostream>
+#include <string>
+
+/// Class for input and output in Mathic's format.
+class MathicIO {
+public:
+ typedef PolyRing::Field BaseField;
+ typedef BaseField::Element Coefficient;
+ typedef BaseField::RawElement RawCoefficient;
+
+ typedef PolyRing::Monoid Monoid;
+ typedef Monoid::MonoRef MonoRef;
+ typedef Monoid::Exponent Exponent;
+ typedef Monoid::VarIndex VarIndex;
+ typedef Monoid::ConstMonoRef ConstMonoRef;
+ typedef Monoid::Order Order;
+ typedef MonoProcessor<Monoid> Processor;
+
+ typedef Order::Gradings Gradings;
+
+/*
+ /// reads ring, #gens, each generator in turn
+ typedef std::tuple<
+ std::unique_ptr<PolyRing>,
+ std::unique_ptr<Basis>,
+ std::unique_ptr<MonoProcessor<PolyRing::Monoid>>
+ > BasisData;
+ BasisData readBasis();
+
+
+
+*/
+ BaseField readBaseField(Scanner& in);
+ void writeBaseField(const BaseField& field, std::ostream& out);
+
+ std::pair<PolyRing, Processor> readRing(
+ const bool withComponent,
+ Scanner& in
+ );
+ void writeRing(
+ const PolyRing& ring,
+ const Processor& processor,
+ const bool withComponent,
+ std::ostream& out
+ );
+
+ Order readOrder(
+ const VarIndex varCount,
+ const bool withComponent,
+ Scanner& in
+ );
+
+ void writeOrder(
+ const Order& order,
+ const bool withComponent,
+ std::ostream& out
+ );
+
+ void readTerm(
+ const PolyRing& ring,
+ const bool readComponent,
+ Coefficient& coef,
+ MonoRef mono,
+ Scanner& in
+ );
+
+ /// Read a monomial with no coefficient. A 1 on its own is not
+ /// considered a coefficient here - it is the monomial with all
+ /// exponents zero and no coefficient.
+ ///
+ /// @todo: Eventually, pick up readComponent from Monoid::HasComponent.
+ void readMonomial(
+ const Monoid& monoid,
+ const bool readComponent,
+ MonoRef mono,
+ Scanner& in
+ );
+
+ /// Read the trailing indicator of the component of a module monomial.
+ void readComponent(
+ const Monoid& monoid,
+ MonoRef mono,
+ Scanner& in
+ );
+
+ /// Print a monomial with no coefficient.
+ void writeMonomial(
+ const Monoid& monoid,
+ const bool writeComponent,
+ ConstMonoRef mono,
+ std::ostream& out
+ );
+};
+
+auto MathicIO::readBaseField(Scanner& in) -> BaseField {
+ return BaseField(in.readInteger<RawCoefficient>());
+}
+
+void MathicIO::writeBaseField(const BaseField& field, std::ostream& out) {
+ out << field.charac();
+}
+
+auto MathicIO::readRing(
+ const bool withComponent,
+ Scanner& in
+) -> std::pair<PolyRing, Processor> {
+ auto baseField = readBaseField(in);
+ const auto varCount = in.readInteger<VarIndex>();
+ auto order = readOrder(varCount, withComponent, in);
+ const bool componentsAscendingDesired = order.componentsAscendingDesired();
+ const bool schreyering = order.schreyering();
+ PolyRing ring(std::move(baseField), Monoid(std::move(order)));
+
+ Processor processor(ring.monoid(), componentsAscendingDesired, schreyering);
+
+ return std::make_pair(std::move(ring), std::move(processor));
+}
+
+void MathicIO::writeRing(
+ const PolyRing& ring,
+ const Processor& processor,
+ const bool withComponent,
+ std::ostream& out
+){
+ writeBaseField(ring.field(), out);
+ out << ' ' << ring.varCount() << '\n';
+
+ auto&& order = ring.monoid().makeOrder(
+ processor.componentsAscendingDesired(),
+ processor.schreyering()
+ );
+ writeOrder(order, withComponent, out);
+}
+
+auto MathicIO::readOrder(
+ const VarIndex varCount,
+ const bool withComponent,
+ Scanner& in
+) -> Order {
+ const bool schreyering = in.match("schreyer");
+ bool lexBaseOrder = !in.match("revlex") && in.match("lex");
+
+ const auto gradingCount = in.readInteger<VarIndex>();
+ bool componentsAscendingDesired = true;
+ auto componentCompareIndex = Order::ComponentAfterBaseOrder;
+ Gradings gradings(static_cast<size_t>(varCount) * gradingCount);
+ size_t index = 0;
+ for (VarIndex grading = 0; grading < gradingCount; ++grading) {
+ const bool com = withComponent && in.match("component");
+ if (withComponent && (com || in.match("revcomponent"))) {
+ if (!Monoid::HasComponent)
+ in.reportError("Cannot specify component comparison for non-modules.");
+ if (componentCompareIndex != Order::ComponentAfterBaseOrder)
+ in.reportError("Component comparison must be specified at most once.");
+ componentsAscendingDesired = com;
+ componentCompareIndex = grading;
+ index += varCount;
+ } else {
+ for (VarIndex i = 0; i < varCount; ++i, ++index)
+ gradings[index] = in.readInteger<Exponent>();
+ }
+ }
+ MATHICGB_ASSERT(index == gradings.size());
+
+ const bool moreLex = in.match("_lex");
+ if (moreLex || in.match("_revlex")) {
+ lexBaseOrder = moreLex;
+ const bool moreCom = withComponent && in.match("component");
+ if (withComponent && (moreCom || in.match("revcomponent")))
+ componentsAscendingDesired = moreCom;
+ }
+
+ Order order(
+ varCount,
+ std::move(gradings),
+ lexBaseOrder ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+ componentCompareIndex,
+ componentsAscendingDesired,
+ schreyering
+ );
+ return std::move(order);
+}
+
+void MathicIO::writeOrder(
+ const Order& order,
+ const bool withComponent,
+ std::ostream& out
+) {
+ MATHICGB_ASSERT(Monoid::HasComponent || !withComponent);
+
+ const auto baseOrder =
+ order.baseOrder() == Order::LexBaseOrder ? "lex" : "revlex";
+ const auto componentOrder =
+ order.componentsAscendingDesired() ? "component" : "revcomponent";
+
+ if (order.schreyering())
+ out << "schreyer ";
+ out << baseOrder << ' ' << order.gradingCount() << '\n';
+ for (VarIndex grading = 0; grading < order.gradingCount(); ++grading) {
+ if (withComponent && grading == order.componentGradingIndex())
+ out << ' ' << componentOrder;
+ else {
+ for (VarIndex var = 0; var < order.varCount(); ++var) {
+ const auto index = var + grading * order.varCount();
+ out << ' ' << unchar(order.gradings()[index]);
+ }
+ }
+ out << '\n';
+ }
+ if (
+ withComponent &&
+ !order.componentsAscendingDesired() &&
+ order.componentGradingIndex() == Order::ComponentAfterBaseOrder
+ ) {
+ out << " _" << baseOrder << "\n " << componentOrder << '\n';
+ }
+}
+
+/*
+auto MathicIO::readBasis() -> BasisData {
+ typedef PolyRing::Monoid Monoid;
+ typedef Monoid::VarIndex VarIndex;
+ typedef Monoid::Gradings Gradings;
+
+ // ** Read prime field
+ const auto charac = mIn.readInteger<coefficient>();
+
+ // ** Read
+ const auto varCount = mIn.readInteger<VarIndex>();
+ const bool doSchreyer = mIn.match("schreyer");
+
+ bool lexBaseOrder = false;
+ if (mIn.match("lex"))
+ lexBaseOrder = true;
+ else if (mIn.match("revlex"))
+ lexBaseOrder = false;
+
+ const auto gradingCount = mIn.readInteger<VarIndex>();
+ bool componentsAscendingDesired = true;
+ auto componentCompareIndex = Order::ComponentAfterBaseOrder;
+ Gradings gradings(static_cast<size_t>(varCount) * gradingCount);
+ size_t index = 0;
+ for (VarIndex grading = 0; grading < gradingCount; ++grading) {
+ const bool com = mIn.match("component");
+ const bool revcom = !com && mIn.match("revcomponent");
+ if (com || revcom) {
+ if (!HasComponent)
+ mIn.reportError("Cannot specify component comparison for non-modules.");
+ componentsAscendingDesired = com;
+ if (componentCompareIndex != Order::ComponentAfterBaseOrder)
+ mIn.reportError("Component comparison must be specified at most once.");
+ componentCompareIndex = grading;
+ index += varCount;
+ } else {
+ for (VarIndex i = 0; i < varCount; ++i, ++index)
+ gradings[index] = mIn.readInteger<Exponent>();
+ }
+ }
+ MATHICGB_ASSERT(index == gradings.size());
+
+ const bool moreRevlex = mIn.match("revlex");
+ const bool moreLex = !moreRevlex && mIn.match("lex");
+ if (moreRevlex || moreLex) {
+ lexBaseOrder = moreLex;
+
+ const bool moreCom = mIn.match("component");
+ const bool moreRevcom = !moreCom && mIn.match("revcomponent");
+ if (com || revcom)
+ componentsAscendingDesired = moreCom;
+ }
+
+ auto ring = make_unique<PolyRing>(
+ charac,
+ Order(
+ varCount,
+ std::move(gradings),
+ lexBaseOrder ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+ componentCompareIndex
+ )
+ );
+ auto basis = make_unique<Basis>(*ring);
+ auto processor = make_unique<MonoProcessor<Monoid>>(ring->monoid());
+ processor->setComponentsAscendingDesired(componentsAscendingDesired);
+
+ // ** Read polynomials
+ const auto polyCount = mIn.readInteger<size_t>();
+ for (size_t i = 0; i < polyCount; ++i) {
+ auto p = readPolynomial();
+ p->sortTermsDescending();
+ basis->insert(std::move(p));
+ }
+
+ if (doSchreyer) {
+ Monoid::MonoVector schreyer(ring->monoid());
+ for (size_t gen = 0; gen < basis->size(); ++gen)
+ schreyer.push_back(basis->getPoly(gen)->getLeadMonomial());
+ processor->setModuleAdjustments(std::move(schreyer));
+ }
+
+ return std::make_tuple(
+ std::move(ring),
+ std::move(basis),
+ std::move(processor)
+ );
+}
+
+std::unique_ptr<Poly> MathicIO::readPolynomial(const PolyRing& ring) {
+ Poly p(ring);
+ if (mIn.match('0'))
+ return;
+
+ auto mono = ring.monoid().alloc();
+ while (true) {
+ if (!isdigit(next) && !isalpha(next) && next != '<')
+ break;
+
+
+ // read coefficient
+ const bool negate = !mIn.match('+') && mIn.match('-');
+ coefficient coef = negate ? -1 : 1;
+ mIn.matchReadInteger(coef, negate);
+
+ // read monomial
+ read
+
+ ring.monoid().setToIdentity(mono);
+
+
+ const size_t firstLocation = monoms.size();
+ monoms.resize(firstLocation + R->maxMonomialSize());
+ monomial m = &monoms[firstLocation];
+ if (isalpha(next) || next == '<')
+ R->monomialParse(i, m);
+ else
+ R->monomialSetIdentity(m); // have to do this to set hash value
+ next = i.peek();
+ if (next == '>')
+ i.get();
+ }
+}
+*/
+
+void MathicIO::readTerm(
+ const PolyRing& ring,
+ const bool readComponent,
+ Coefficient& coef,
+ MonoRef mono,
+ Scanner& in
+) {
+ // ** Read coefficient, if any.
+ const auto& field = ring.field();
+ const bool negate = !in.match('+') && in.match('-');
+ if (in.peekDigit())
+ coef = field.toElement(in.readInteger<RawCoefficient>(negate));
+ else if (negate)
+ coef = field.minusOne();
+ else
+ coef = field.one();
+
+ // ** Read monomial
+ auto& monoid = ring.monoid();
+ if (field.isOne(coef) && !in.peekAlpha()) {
+ // Detect the monomial 1.
+ monoid.setIdentity(mono);
+ if (readComponent)
+ this->readComponent(monoid, mono, in);
+ } else
+ readMonomial(monoid, readComponent, mono, in);
+}
+
+void MathicIO::readMonomial(
+ const Monoid& monoid,
+ const bool readComponent,
+ MonoRef mono,
+ Scanner& in
+) {
+ MATHICGB_ASSERT(!readComponent || Monoid::HasComponent);
+
+ monoid.setIdentity(mono);
+ if (in.peek() == '1') {
+ const auto e = in.readInteger<Exponent>();
+ if (e != 1) {
+ std::ostringstream err;
+ err << "Expected monomial, but got " << e << " (did you mean 1?).";
+ in.reportError(err.str());
+ }
+ } else {
+ bool sawSome = false;
+ while (true) {
+ const auto letterCount = 'z' - 'a' + 1;
+ const auto letter = in.peek();
+
+ VarIndex var;
+ if ('a' <= letter && letter <= 'z')
+ var = letter - 'a';
+ else if ('A' <= letter && letter <= 'Z')
+ var = (letter - 'A') + letterCount;
+ else if (sawSome)
+ break;
+ else {
+ std::ostringstream err;
+ err << "Expected letter while reading monomial, but got '"
+ << static_cast<char>(letter) << "'.";
+ in.reportError(err.str());
+ return;
+ }
+ in.get(); // skip past letter
+
+ MATHICGB_ASSERT(var < 2 * letterCount);
+ if (var >= monoid.varCount()) {
+ std::ostringstream err;
+ err << "Saw the variable " << static_cast<char>(letter)
+ << ", but the monoid only has "
+ << monoid.varCount() << " variables.";
+ in.reportError(err.str());
+ return;
+ }
+ if (monoid.exponent(mono, var) > static_cast<Exponent>(0)) {
+ std::ostringstream err;
+ err << "Variable " << static_cast<char>(letter) <<
+ " must not be written twice in one monomial.";
+ in.reportError(err.str());
+ }
+
+ if (in.peekDigit())
+ monoid.setExponent(var, in.readInteger<Exponent>(), mono);
+ else
+ monoid.setExponent(var, static_cast<Exponent>(1), mono);
+ sawSome = true;
+ }
+ }
+
+ if (readComponent)
+ this->readComponent(monoid, mono, in);
+}
+
+void MathicIO::readComponent(
+ const Monoid& monoid,
+ MonoRef mono,
+ Scanner& in
+) {
+ MATHICGB_ASSERT(Monoid::HasComponent);
+ in.expect('<');
+ monoid.setComponent(in.readInteger<Exponent>(), mono);
+ in.expect('>');
+}
+
+/// Print a monomial with no coefficient.
+void MathicIO::writeMonomial(
+ const Monoid& monoid,
+ const bool writeComponent,
+ ConstMonoRef mono,
+ std::ostream& out
+) {
+ const auto letterCount = 'z' - 'a' + 1;
+
+ bool printedSome = false;
+ for (VarIndex var = 0; var < monoid.varCount(); ++var) {
+ if (monoid.exponent(mono, var) == 0)
+ continue;
+ char letter;
+ if (var < letterCount)
+ letter = 'a' + static_cast<char>(var);
+ else if (var < 2 * letterCount)
+ letter = 'A' + (static_cast<char>(var) - letterCount);
+ else {
+ mathic::reportError("Too few letters in alphabet to print variable.");
+ return;
+ }
+ printedSome = true;
+ out << letter;
+ if (monoid.exponent(mono, var) != 1)
+ out << unchar(monoid.exponent(mono, var));
+ }
+ if (!printedSome)
+ out << '1';
+ if (writeComponent) {
+ MATHICGB_ASSERT(Monoid::HasComponent);
+ out << '<' << unchar(monoid.component(mono)) << '>';
+ }
+}
+
+#endif
diff --git a/src/mathicgb/MonoMonoid.hpp b/src/mathicgb/MonoMonoid.hpp
index baaf447..21f6024 100755
--- a/src/mathicgb/MonoMonoid.hpp
+++ b/src/mathicgb/MonoMonoid.hpp
@@ -65,9 +65,8 @@ namespace MonoMonoidInternal {
mLexBaseOrder(order.baseOrder() == Order::LexBaseOrder),
mGradings(makeGradings(order)),
mComponentGradingIndex(
- order.componentGradingIndex() == Order::ComponentAfterBaseOrder ?
- Order::ComponentAfterBaseOrder :
- order.gradingCount() - 1 - order.componentGradingIndex()
+ reverseComponentGradingIndex
+ (order.gradingCount(), order.componentGradingIndex())
)
{
}
@@ -119,6 +118,19 @@ namespace MonoMonoidInternal {
gradings[i] = -gradings[i];
}
+ /// Since comparisons go opposite direction, we need to reverse
+ /// the component grading index, unless it's the special value
+ /// indicating that it goes last.
+ static VarIndex reverseComponentGradingIndex(
+ const VarIndex gradingCount,
+ const VarIndex componentGradingIndex
+ ) {
+ if (componentGradingIndex == Order::ComponentAfterBaseOrder)
+ return Order::ComponentAfterBaseOrder;
+ else
+ return gradingCount - 1 - componentGradingIndex;
+ }
+
const HashCoefficients& hashCoefficients() const {return mHashCoefficients;}
bool orderIsTotalDegreeRevLex() const {return mOrderIsTotalDegreeRevLex;}
Gradings& gradings() {return mGradings;} // todo: remove this overload
@@ -340,6 +352,30 @@ public:
void printMonoid
(const bool componentsAscendingDesired, std::ostream& out) const;
+ /// Returns an Order object that is equivalent to the order that
+ /// this monoid was constructed with. The settings not handled by
+ /// the monoid, and therefore not known by the monoid, are passed in
+ /// as parameters. The purpose of that is to make it clear that this
+ /// information must be supplied separately.
+ Order makeOrder(
+ const bool componentsAscendingDesired,
+ const bool schreyering
+ ) const {
+ std::vector<Exponent> orderGradings(gradings());
+ reverseGradings(varCount(), orderGradings);
+ if (!isLexBaseOrder())
+ negateGradings(orderGradings);
+ return Order(
+ varCount(),
+ std::move(orderGradings),
+ isLexBaseOrder() ? Order::LexBaseOrder : Order::RevLexBaseOrder,
+ Base::reverseComponentGradingIndex
+ (gradingCount(), componentGradingIndex()),
+ componentsAscendingDesired,
+ schreyering
+ );
+ }
+
bool operator==(const MonoMonoid& monoid) const {
return this == &monoid;
}
diff --git a/src/mathicgb/MonoOrder.hpp b/src/mathicgb/MonoOrder.hpp
index 7045110..e6770ba 100755
--- a/src/mathicgb/MonoOrder.hpp
+++ b/src/mathicgb/MonoOrder.hpp
@@ -4,7 +4,7 @@
#include <vector>
#include <algorithm>
-/// Class used to describe an monomial order or a module monomial
+/// Class used to describe an monomial order and/or a module monomial
/// order. Use this class to construct a monoid. The monoid does the
/// actual comparisons.
///
@@ -36,13 +36,17 @@ public:
MonoOrder(
const VarIndex varCount,
const BaseOrder baseOrder = RevLexBaseOrder,
- const size_t componentBefore = ComponentAfterBaseOrder
+ const size_t componentBefore = ComponentAfterBaseOrder,
+ const bool componentsAscendingDesired = true,
+ const bool schreyering = true
):
mVarCount(varCount),
mGradings
(addComponentGrading(Gradings(varCount, 1), varCount, componentBefore)),
mBaseOrder(baseOrder),
- mComponentGradingIndex(componentBefore)
+ mComponentGradingIndex(componentBefore),
+ mComponentsAscendingDesired(componentsAscendingDesired),
+ mSchreyering(schreyering)
{}
/// The specified base order is graded by the gradings matrix.
@@ -81,12 +85,16 @@ public:
const VarIndex varCount,
Gradings&& gradings,
const BaseOrder baseOrder = RevLexBaseOrder,
- const size_t componentBefore = ComponentAfterBaseOrder
+ const size_t componentBefore = ComponentAfterBaseOrder,
+ const bool componentsAscendingDesired = true,
+ const bool schreyering = true
):
mVarCount(varCount),
mGradings(std::move(gradings)),
mBaseOrder(baseOrder),
- mComponentGradingIndex(componentBefore)
+ mComponentGradingIndex(componentBefore),
+ mComponentsAscendingDesired(componentsAscendingDesired),
+ mSchreyering(schreyering)
{
#ifdef MATHCGB_DEBUG
if (componentBefore != ComponentAfterBaseOrder) {
@@ -152,6 +160,9 @@ public:
return true;
}
+ bool componentsAscendingDesired() const {return mComponentsAscendingDesired;}
+ bool schreyering() const {return mSchreyering;}
+
private:
static Gradings addComponentGrading(
Gradings&& gradings,
@@ -189,9 +200,12 @@ private:
}
const VarIndex mVarCount;
+
const Gradings mGradings;
const BaseOrder mBaseOrder;
const size_t mComponentGradingIndex;
+ const bool mSchreyering;
+ const bool mComponentsAscendingDesired;
};
#endif
diff --git a/src/mathicgb/MonoProcessor.hpp b/src/mathicgb/MonoProcessor.hpp
index 2457ec7..7f7c84e 100755
--- a/src/mathicgb/MonoProcessor.hpp
+++ b/src/mathicgb/MonoProcessor.hpp
@@ -20,9 +20,14 @@ public:
typedef typename Monoid::ConstMonoRef ConstMonoRef;
typedef typename Monoid::ConstMonoPtr ConstMonoPtr;
- MonoProcessor(const Monoid& monoid):
- mComponentsAscendingDesired(true),
+ MonoProcessor(
+ const Monoid& monoid,
+ const bool componentsAscendingDesired,
+ const bool schreyering
+ ):
+ mComponentsAscendingDesired(componentsAscendingDesired),
mComponentCount(0),
+ mSchreyering(schreyering),
mModuleAdjustmentsMemory(monoid)
{}
@@ -83,6 +88,9 @@ public:
return !mModuleAdjustments.empty();
}
+ void setSchreyering(bool value) {mSchreyering = true;}
+ bool schreyering() const {return mSchreyering;}
+
void setComponentCount(VarIndex count) {mComponentCount = count;}
VarIndex componentCount() const {return mComponentCount;}
const Monoid& monoid() const {return mModuleAdjustmentsMemory.monoid();}
@@ -106,6 +114,7 @@ private:
bool mComponentsAscendingDesired;
VarIndex mComponentCount;
+ bool mSchreyering;
MonoVector mModuleAdjustmentsMemory;
std::vector<ConstMonoPtr> mModuleAdjustments;
};
diff --git a/src/mathicgb/PrimeField.hpp b/src/mathicgb/PrimeField.hpp
index 009c8ad..4dcf4f3 100755
--- a/src/mathicgb/PrimeField.hpp
+++ b/src/mathicgb/PrimeField.hpp
@@ -11,6 +11,8 @@
template<class T>
class PrimeField {
public:
+ typedef T RawElement;
+
class Element {
public:
static_assert(!std::numeric_limits<T>::is_signed, "");
@@ -39,6 +41,7 @@ public:
Element zero() const {return Element(0);}
Element one() const {return Element(1);}
+ Element minusOne() const {return Element(charac() - 1);}
bool isZero(const Element a) const {return a == zero();}
bool isOne(const Element a) const {return a == one();}
diff --git a/src/mathicgb/Scanner.cpp b/src/mathicgb/Scanner.cpp
index 6fb10dd..caab861 100755
--- a/src/mathicgb/Scanner.cpp
+++ b/src/mathicgb/Scanner.cpp
@@ -175,7 +175,8 @@ bool Scanner::readBuffer(size_t minRead) {
mStream->read(readInto, readCount);
didReadCount = mStream->gcount();
}
- mBuffer.resize(didReadCount);
+ mBuffer.resize(saveCount + didReadCount);
mBufferPos = mBuffer.begin();
+
return didReadCount >= minRead;
}
diff --git a/src/test/MathicIO.cpp b/src/test/MathicIO.cpp
new file mode 100755
index 0000000..8d17fd5
--- /dev/null
+++ b/src/test/MathicIO.cpp
@@ -0,0 +1,171 @@
+#include "mathicgb/stdinc.h"
+#include "mathicgb/MathicIO.hpp"
+
+#include <gtest/gtest.h>
+
+TEST(MathicIO, ReadWriteRing) {
+ typedef PolyRing::Monoid Monoid;
+ typedef Monoid::VarIndex VarIndex;
+ typedef Monoid::Exponent Exponent;
+ typedef PolyRing::Field BaseField;
+ typedef BaseField::RawElement RawElement;
+
+ auto check = [&](
+ const char* const inStr,
+ const char* outStr,
+ const RawElement charac,
+ const VarIndex varCount,
+ const VarIndex gradingCount,
+ const bool withComponent
+ ) {
+ for (int i = 0; i < 2; ++i) {
+ const char* str = i == 0 ? inStr : outStr;
+ if (str == 0)
+ continue;
+ Scanner in(str);
+ auto p = MathicIO().readRing(withComponent, in);
+ auto& monoid = p.first.monoid();
+ ASSERT_EQ(charac, p.first.field().charac());
+ ASSERT_EQ(varCount, monoid.varCount());
+ ASSERT_EQ(gradingCount, monoid.gradingCount());
+ std::ostringstream out;
+ MathicIO().writeRing(p.first, p.second, withComponent, out);
+ ASSERT_EQ(outStr, out.str());
+ }
+ };
+
+ check("101 2 1 3 4", "101 2\nrevlex 1\n 3 4\n", 101, 2, 1, false);
+ check(
+ "101 2 schreyer lex 1 3 4 _lex revcomponent",
+ "101 2\nschreyer lex 1\n 3 4\n _lex\n revcomponent\n", 101, 2, 1, true
+ );
+ check(
+ "101 2 2 component 3 4",
+ "101 2\nrevlex 2\n component\n 3 4\n", 101, 2, 2, true
+ );
+}
+
+TEST(MathicIO, ReadWriteMonomial) {
+ typedef PolyRing::Monoid Monoid;
+ typedef Monoid::VarIndex VarIndex;
+ typedef Monoid::Exponent Exponent;
+ static const auto NoComponent = static_cast<Exponent>(-1);
+
+ Monoid m(28);
+
+ // canonicalStr is str as it should appear after being read and
+ // printed. If canonicalStr is null then this is the same as str.
+ auto check = [&](
+ const char* const str,
+ const Exponent component,
+ const VarIndex var1 = -1,
+ const Exponent exp1 = -1,
+ const VarIndex var2 = -1,
+ const Exponent exp2 = -1,
+ const char* const canonicalStr = 0
+ ) {
+ const bool doComponent = component != NoComponent;
+
+ // read monomial from string
+ auto monoRead = m.alloc();
+ Scanner in(str);
+ MathicIO().readMonomial(m, doComponent, monoRead, in);
+
+ // directly make monomial
+ auto monoSet = m.alloc();
+ if (var1 != -1)
+ m.setExponent(var1, exp1, monoSet);
+ if (var2 != -1)
+ m.setExponent(var2, exp2, monoSet);
+ if (doComponent)
+ m.setComponent(component, monoSet);
+ ASSERT_TRUE(m.equal(monoRead, monoSet)) << "Str: " << str;
+
+ // print monomial
+ std::ostringstream out;
+ MathicIO().writeMonomial(m, doComponent, monoRead, out);
+ const auto correctStr = canonicalStr == 0 ? str : canonicalStr;
+ ASSERT_EQ(correctStr, out.str());
+ };
+
+ check("1", NoComponent);
+ check("1<0>", 0);
+ check("1<1>", 1);
+ check("1<999>", 999);
+
+ check("a1", NoComponent, 0,1, -1,-1, "a");
+ check("b10<0>", 0, 1,10);
+ check("A11", NoComponent, 26,11);
+ check("B99<1>", 1, 27,99);
+
+ check("ab", NoComponent, 0,1, 1,1);
+ check("ba", NoComponent, 0,1, 1,1, "ab");
+ check("a0c3b1", NoComponent, 1,1, 2,3, "bc3");
+ check("ab<2>", 2, 0,1, 1,1);
+}
+
+// TODO: check readTerm
+
+TEST(MathicIO, ReadWriteBaseField) {
+ Scanner in("101");
+ auto field = MathicIO().readBaseField(in);
+ ASSERT_EQ(101, field.charac());
+ std::ostringstream out;
+ MathicIO().writeBaseField(field, out);
+ ASSERT_EQ("101", out.str());
+}
+
+TEST(MathicIO, ReadWriteOrder) {
+ typedef PolyRing::Monoid Monoid;
+ typedef Monoid::VarIndex VarIndex;
+
+ const auto check = [](
+ const char* const inStr,
+ const char* const outStr,
+ const VarIndex varCount,
+ const VarIndex gradingCount,
+ const bool withComponent = false,
+ const bool componentsAscendingDesired = true,
+ const bool schreyering = false
+ ) -> void {
+ for (int i = 0; i < 2; ++i) {
+ const char* str = i == 0 ? inStr : outStr;
+ if (str == 0)
+ continue;
+
+ Scanner in(str);
+ const auto order = MathicIO().readOrder(varCount, withComponent, in);
+ ASSERT_EQ(varCount, order.varCount());
+ ASSERT_EQ(gradingCount, order.gradingCount());
+ ASSERT_EQ(componentsAscendingDesired, order.componentsAscendingDesired());
+ ASSERT_EQ(schreyering, order.schreyering()) << inStr;
+
+ std::ostringstream out;
+ MathicIO().writeOrder(order, withComponent, out);
+ ASSERT_EQ(outStr, out.str());
+ }
+ };
+ check("0\n", "revlex 0\n", 0, 0);
+ check("1\n 2\n", "revlex 1\n 2\n", 1, 1);
+ check("2\n 3\n 4\n", "revlex 2\n 3\n 4\n", 1, 2);
+ check("2\n 3 4\n 5 6\n", "revlex 2\n 3 4\n 5 6\n", 2, 2);
+ check("1\n 1 1 1 1\n", "revlex 1\n 1 1 1 1\n", 4, 1);
+
+ check("lex 0", "lex 0\n", 0, 0);
+ check("lex 1 2", "lex 1\n 2\n", 1, 1);
+ check("lex 2 3 4", "lex 2\n 3\n 4\n", 1, 2);
+ check("lex 2 3 4 5 6", "lex 2\n 3 4\n 5 6\n", 2, 2);
+ check("lex 1 1 1 1 1", "lex 1\n 1 1 1 1\n", 4, 1);
+
+ check("2 component\n 5 6\n", "revlex 2\n component\n 5 6\n", 2, 2, 1, 1, 0);
+ check("2 3 4\nrevcomponent\n","revlex 2\n 3 4\n revcomponent\n",2,2, 1,0,0);
+ check("lex 1 component", "lex 0\n", 0, 0, 1, 1, 0);
+ check("lex 1 revcomponent", "lex 1\n revcomponent\n", 1, 1, 1, 0, 0);
+ check("lex 1 revcomponent", "lex 1\n revcomponent\n", 5, 1, 1, 0, 0);
+
+ check(
+ "schreyer lex 1 1 _lex revcomponent",
+ "schreyer lex 1\n 1\n _lex\n revcomponent\n",
+ 1, 1, 1, 0, 1
+ );
+}
--
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