[mathicgb] 377/393: Poly mostly clean now.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:36 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 a73276e655d8b6eadcfac9bfe5924fe913a9ebc8
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Thu Sep 19 17:02:28 2013 +0200

    Poly mostly clean now.
---
 Makefile.am                                        |  51 ++--
 build/vs12/mathicgb-lib/mathicgb-lib.vcxproj       |   2 +
 .../vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters |   6 +
 src/cli/GBAction.cpp                               |  20 +-
 src/mathicgb/ClassicGBAlg.cpp                      |   3 +-
 src/mathicgb/F4MatrixBuilder.cpp                   |  12 +-
 src/mathicgb/F4MatrixBuilder.hpp                   |   4 +-
 src/mathicgb/F4MatrixProjection.cpp                |   5 +-
 src/mathicgb/F4ProtoMatrix.cpp                     |  12 +-
 src/mathicgb/F4ProtoMatrix.hpp                     |  10 +-
 src/mathicgb/MathicIO.hpp                          |  34 ++-
 src/mathicgb/Poly.cpp                              | 202 ++-------------
 src/mathicgb/Poly.hpp                              | 275 ++++++++++++---------
 src/mathicgb/PrimeField.hpp                        |   7 +
 src/mathicgb/Range.hpp                             |  44 ++++
 src/mathicgb/ReducerHashPack.cpp                   |   4 +-
 src/mathicgb/ReducerPack.cpp                       |   4 +-
 src/mathicgb/ReducerPackDedup.cpp                  |   4 +-
 src/mathicgb/SigPolyBasis.cpp                      |   4 +-
 src/mathicgb/TypicalReducer.cpp                    |   9 +-
 src/mathicgb/io-util.cpp                           |  25 +-
 src/mathicgb/io-util.hpp                           |   1 -
 src/test/F4MatrixBuilder.cpp                       |  25 +-
 src/test/F4MatrixReducer.cpp                       |   5 +-
 src/test/MathicIO.cpp                              |   9 +-
 src/test/QuadMatrixBuilder.cpp                     |  12 +-
 src/test/SparseMatrix.cpp                          |   6 +-
 src/test/poly-test.cpp                             |  40 ++-
 28 files changed, 397 insertions(+), 438 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index f8273a8..4d136c9 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,31 +13,32 @@ 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/ReducerPack.hpp					\
-  src/mathicgb/ReducerPack.cpp src/mathicgb/ClassicGBAlg.cpp			\
-  src/mathicgb/ClassicGBAlg.hpp src/mathicgb/MonoLookup.hpp				\
-  src/mathicgb/MonoLookup.cpp src/mathicgb/StaticMonoMap.hpp			\
-  src/mathicgb/SigPolyBasis.cpp src/mathicgb/SigPolyBasis.hpp			\
-  src/mathicgb/Basis.cpp src/mathicgb/Basis.hpp							\
-  src/mathicgb/io-util.cpp src/mathicgb/io-util.hpp						\
-  src/mathicgb/KoszulQueue.hpp src/mathicgb/ModuleMonoSet.cpp			\
-  src/mathicgb/ModuleMonoSet.hpp src/mathicgb/Poly.cpp					\
-  src/mathicgb/Poly.hpp src/mathicgb/PolyBasis.cpp						\
-  src/mathicgb/PolyBasis.hpp src/mathicgb/PolyHashTable.cpp				\
-  src/mathicgb/PolyHashTable.hpp src/mathicgb/PolyRing.cpp				\
-  src/mathicgb/PolyRing.hpp src/mathicgb/Reducer.cpp					\
-  src/mathicgb/Reducer.hpp src/mathicgb/ReducerDedup.hpp				\
-  src/mathicgb/ReducerDedup.cpp src/mathicgb/ReducerHash.hpp			\
-  src/mathicgb/ReducerHash.cpp src/mathicgb/ReducerHashPack.hpp			\
-  src/mathicgb/ReducerHashPack.cpp src/mathicgb/ReducerHelper.hpp		\
-  src/mathicgb/ReducerNoDedup.hpp src/mathicgb/ReducerNoDedup.cpp		\
-  src/mathicgb/ReducerPackDedup.hpp src/mathicgb/ReducerPackDedup.cpp	\
-  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/SigSPairQueue.hpp					\
-  src/mathicgb/SigSPairQueue.cpp src/mathicgb/SparseMatrix.hpp			\
-  src/mathicgb/SparseMatrix.cpp src/mathicgb/QuadMatrixBuilder.hpp		\
+libmathicgb_la_SOURCES = src/mathicgb/Zip.hpp src/mathicgb/Range.hpp	\
+  src/mathicgb/ReducerPack.hpp src/mathicgb/ReducerPack.cpp				\
+  src/mathicgb/ClassicGBAlg.cpp src/mathicgb/ClassicGBAlg.hpp			\
+  src/mathicgb/MonoLookup.hpp src/mathicgb/MonoLookup.cpp				\
+  src/mathicgb/StaticMonoMap.hpp src/mathicgb/SigPolyBasis.cpp			\
+  src/mathicgb/SigPolyBasis.hpp src/mathicgb/Basis.cpp					\
+  src/mathicgb/Basis.hpp src/mathicgb/io-util.cpp						\
+  src/mathicgb/io-util.hpp src/mathicgb/KoszulQueue.hpp					\
+  src/mathicgb/ModuleMonoSet.cpp src/mathicgb/ModuleMonoSet.hpp			\
+  src/mathicgb/Poly.cpp src/mathicgb/Poly.hpp							\
+  src/mathicgb/PolyBasis.cpp src/mathicgb/PolyBasis.hpp					\
+  src/mathicgb/PolyHashTable.cpp src/mathicgb/PolyHashTable.hpp			\
+  src/mathicgb/PolyRing.cpp src/mathicgb/PolyRing.hpp					\
+  src/mathicgb/Reducer.cpp src/mathicgb/Reducer.hpp						\
+  src/mathicgb/ReducerDedup.hpp src/mathicgb/ReducerDedup.cpp			\
+  src/mathicgb/ReducerHash.hpp src/mathicgb/ReducerHash.cpp				\
+  src/mathicgb/ReducerHashPack.hpp src/mathicgb/ReducerHashPack.cpp		\
+  src/mathicgb/ReducerHelper.hpp src/mathicgb/ReducerNoDedup.hpp		\
+  src/mathicgb/ReducerNoDedup.cpp src/mathicgb/ReducerPackDedup.hpp		\
+  src/mathicgb/ReducerPackDedup.cpp 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/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			\
diff --git a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
index 3236d3c..674e3ae 100755
--- a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
+++ b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
@@ -509,6 +509,7 @@
     <ClInclude Include="..\..\..\src\mathicgb\PrimeField.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\QuadMatrix.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\QuadMatrixBuilder.hpp" />
+    <ClInclude Include="..\..\..\src\mathicgb\Range.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\RawVector.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\Reducer.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\ReducerDedup.hpp" />
@@ -530,6 +531,7 @@
     <ClInclude Include="..\..\..\src\mathicgb\stdinc.h" />
     <ClInclude Include="..\..\..\src\mathicgb\TypicalReducer.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\Unchar.hpp" />
+    <ClInclude Include="..\..\..\src\mathicgb\Zip.hpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
index e8f37ab..ccd539c 100755
--- a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
+++ b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
@@ -280,5 +280,11 @@
     <ClInclude Include="..\..\..\src\mathicgb\ReducerPack.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\src\mathicgb\Range.hpp">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\src\mathicgb\Zip.hpp">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/src/cli/GBAction.cpp b/src/cli/GBAction.cpp
index ee5a2b4..d0b06dc 100755
--- a/src/cli/GBAction.cpp
+++ b/src/cli/GBAction.cpp
@@ -99,19 +99,13 @@ void GBAction::performAction() {
   alg.computeGrobnerBasis();
   alg.printStats(std::cerr);
 
-  if (mGBParams.mOutputResult.value())
-    {
-      // output Groebner basis into .gb file.
-
-      // The stats information is displayed to cout (above),
-      // so we disable it here.
-      // std::ofstream statsOut((projectName + ".stats").c_str());
-      // alg.printStats(statsOut);
-
-      std::string basisFileName = projectName + ".gb";
-      FILE* basisOut = std::fopen(basisFileName.c_str(), "w");
-      output(basisOut, alg.basis());
-    }
+  if (mGBParams.mOutputResult.value()) {
+    // output Groebner basis into .gb file.
+
+    std::string basisFileName = projectName + ".gb";
+    std::ofstream out(basisFileName);
+    output(out, alg.basis());
+  }
 }
 
 const char* GBAction::staticName() {
diff --git a/src/mathicgb/ClassicGBAlg.cpp b/src/mathicgb/ClassicGBAlg.cpp
index 0626b04..d6c20d3 100755
--- a/src/mathicgb/ClassicGBAlg.cpp
+++ b/src/mathicgb/ClassicGBAlg.cpp
@@ -5,6 +5,7 @@
 
 #include "Basis.hpp"
 #include "LogDomain.hpp"
+#include "MathicIO.hpp"
 #include <iostream>
 
 MATHICGB_DEFINE_LOG_DOMAIN(
@@ -132,7 +133,7 @@ void ClassicGBAlg::insertReducedPoly(
   if (tracingLevel > 20) {
     std::cerr << "inserting basis element " << mBasis.size() << ": ";
     if (tracingLevel > 100) {
-      polyToInsert->display(std::cerr);
+      MathicIO<>().writePoly(*polyToInsert, false, std::cerr);
       std::cerr << std::endl;
     } else {
       mRing.printMonomialFrobbyM2Format
diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
index 4feefc1..7f932d7 100755
--- a/src/mathicgb/F4MatrixBuilder.cpp
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -274,8 +274,8 @@ auto F4MatrixBuilder::createColumn(
 void F4MatrixBuilder::appendRowBottom(
   ConstMonoRef multiple,
   const bool negate,
-  const Poly::const_iterator begin,
-  const Poly::const_iterator end,
+  const Poly::ConstTermIterator begin,
+  const Poly::ConstTermIterator end,
   QuadMatrixBuilder& builder,
   TaskFeeder& feeder
 ) {
@@ -363,12 +363,12 @@ void F4MatrixBuilder::appendRowBottom(
   TaskFeeder& feeder
 ) {
   MATHICGB_ASSERT(!poly.isZero());
-  Poly::const_iterator itA = poly.begin();
-  const Poly::const_iterator endA = poly.end();
+  auto itA = poly.begin();
+  const auto endA = poly.end();
 
   MATHICGB_ASSERT(!sPairPoly.isZero());
-  Poly::const_iterator itB = sPairPoly.begin();
-  Poly::const_iterator endB = sPairPoly.end();
+  auto itB = sPairPoly.begin();
+  const auto endB = sPairPoly.end();
 
   // skip leading terms since they cancel
   MATHICGB_ASSERT(itA.coef() == itB.coef());
diff --git a/src/mathicgb/F4MatrixBuilder.hpp b/src/mathicgb/F4MatrixBuilder.hpp
index a1ab4d7..0d4d384 100755
--- a/src/mathicgb/F4MatrixBuilder.hpp
+++ b/src/mathicgb/F4MatrixBuilder.hpp
@@ -122,8 +122,8 @@ private:
   void appendRowBottom(
     ConstMonoRef multiple,
     bool negate,
-    Poly::const_iterator begin,
-    Poly::const_iterator end,
+    Poly::ConstTermIterator begin,
+    Poly::ConstTermIterator end,
     QuadMatrixBuilder& builder,
     TaskFeeder& feeder
   );
diff --git a/src/mathicgb/F4MatrixProjection.cpp b/src/mathicgb/F4MatrixProjection.cpp
index 5f9ac15..d87abd1 100755
--- a/src/mathicgb/F4MatrixProjection.cpp
+++ b/src/mathicgb/F4MatrixProjection.cpp
@@ -154,10 +154,9 @@ public:
 
   void appendRow(const Row& row) {
     MATHICGB_ASSERT(row.entryCount > 0); // could be OK, but unexpected
-    MATHICGB_ASSERT(row.scalars == 0 || row.externalScalars == 0);
 
     const auto indicesEnd = row.indices + row.entryCount;
-    if (row.externalScalars != 0)
+    if (row.scalars == nullptr)
       appendRow(row.indices, indicesEnd, row.externalScalars);
     else
       appendRow(row.indices, indicesEnd, row.scalars);
@@ -245,7 +244,7 @@ QuadMatrix F4MatrixProjection::makeAndClearOneStep(const size_t quantum) {
         MATHICGB_ASSERT(row.indices[lead] < mColProjectTo.size());
         auto const projected = mColProjectTo[row.indices[lead]];
         if (projected.isLeft) {
-          const auto leadScalar = row.scalars != 0 ?
+          const auto leadScalar = row.scalars != nullptr ?
             row.scalars[lead] :
             static_cast<Scalar>(row.externalScalars[lead]);
           tb.addRow(row, projected.index, leadScalar);
diff --git a/src/mathicgb/F4ProtoMatrix.cpp b/src/mathicgb/F4ProtoMatrix.cpp
index bc7e091..64d81e1 100755
--- a/src/mathicgb/F4ProtoMatrix.cpp
+++ b/src/mathicgb/F4ProtoMatrix.cpp
@@ -11,11 +11,10 @@ auto F4ProtoMatrix::row(const RowIndex row) const -> Row {
   Row rr;
   rr.indices = mIndices.data() + r.indicesBegin;
   rr.entryCount = r.entryCount;
-  if (r.externalScalars == 0) {
+  if (!r.scalarsStoredExternally) {
     rr.scalars = mScalars.data() + r.scalarsBegin;
-    rr.externalScalars = 0;
   } else {
-    rr.scalars = 0;
+    rr.scalars = nullptr;
     rr.externalScalars = r.externalScalars;
   }
   return rr;
@@ -30,7 +29,8 @@ auto F4ProtoMatrix::makeRowWithTheseScalars(const Poly& scalars) -> ColIndex*
   row.indicesBegin = mIndices.size();
   row.scalarsBegin = std::numeric_limits<decltype(row.scalarsBegin)>::max();
   row.entryCount = static_cast<ColIndex>(scalars.termCount());
-  row.externalScalars = scalars.coefficientBegin();
+  row.scalarsStoredExternally = true;
+  row.externalScalars = scalars.coefBegin();
   mRows.push_back(row);
 
   mIndices.resize(mIndices.size() + row.entryCount);
@@ -44,7 +44,7 @@ auto F4ProtoMatrix::makeRow(ColIndex entryCount) -> std::pair<ColIndex*, Scalar*
   row.indicesBegin = mIndices.size();
   row.scalarsBegin = mScalars.size();
   row.entryCount = entryCount;
-  row.externalScalars = 0;
+  row.scalarsStoredExternally = false;
   mRows.push_back(row);
 
   mIndices.resize(mIndices.size() + entryCount);
@@ -62,7 +62,7 @@ void F4ProtoMatrix::removeLastEntries(const RowIndex row, const ColIndex count)
   if (row != rowCount() - 1)
     return;
   mIndices.resize(mIndices.size() - count);
-  if (mRows[row].externalScalars == 0)
+  if (!mRows[row].scalarsStoredExternally)
     mScalars.resize(mScalars.size() - count);
 }
 
diff --git a/src/mathicgb/F4ProtoMatrix.hpp b/src/mathicgb/F4ProtoMatrix.hpp
index 6648050..d4efd45 100755
--- a/src/mathicgb/F4ProtoMatrix.hpp
+++ b/src/mathicgb/F4ProtoMatrix.hpp
@@ -13,13 +13,16 @@ class F4ProtoMatrix {
 public:
   typedef uint32 RowIndex;
   typedef uint32 ColIndex;
-  typedef coefficient ExternalScalar;
   typedef SparseMatrix::Scalar Scalar;
+  typedef coefficient ExternalScalar;
+  typedef Poly::ConstCoefIterator ExternalConstCoefIterator;
 
   struct Row {
+    Row(): indices(), scalars(), externalScalars(), entryCount() {}
+
     const ColIndex* indices;
     const Scalar* scalars;
-    const ExternalScalar* externalScalars;
+    ExternalConstCoefIterator externalScalars;
     ColIndex entryCount;
   };
 
@@ -38,7 +41,8 @@ private:
     size_t indicesBegin;
     size_t scalarsBegin;
     ColIndex entryCount;
-    const ExternalScalar* externalScalars;
+    bool scalarsStoredExternally;
+    ExternalConstCoefIterator externalScalars;
   };
 
   std::vector<ColIndex> mIndices;
diff --git a/src/mathicgb/MathicIO.hpp b/src/mathicgb/MathicIO.hpp
index 23449d6..4193e76 100755
--- a/src/mathicgb/MathicIO.hpp
+++ b/src/mathicgb/MathicIO.hpp
@@ -80,12 +80,17 @@ public:
     std::ostream& out
   );
 
-  Poly readPoly(
+  /// Reads a polynomial and does not reorder the terms to be in descending
+  /// order.
+  Poly readPolyDoNotOrder(
     const PolyRing& ring,
     const bool readComponent,
     Scanner& in
   );
 
+  /// Reads a polynomial and orders the terms in descending order.
+  Poly readPoly(const PolyRing& ring, const bool readComponent, Scanner& in);
+
   void writePoly(
     const Poly& poly,
     const bool writeComponent,
@@ -105,6 +110,7 @@ public:
     const bool writeComponent,
     const Coefficient coef,
     ConstMonoRef mono,
+    bool writeSignEvenIfPositive,
     std::ostream& out
   );
 
@@ -372,6 +378,17 @@ Poly MathicIO<M, BF>::readPoly(
   const bool readComponent,
   Scanner& in
 ) {
+  auto p = readPolyDoNotOrder(ring, readComponent, in);
+  p.sortTermsDescending();
+  return p;
+}
+
+template<class M, class BF>
+Poly MathicIO<M, BF>::readPolyDoNotOrder(
+  const PolyRing& ring,
+  const bool readComponent,
+  Scanner& in
+) {
   Poly p(ring);
 
   // also skips whitespace
@@ -382,7 +399,7 @@ Poly MathicIO<M, BF>::readPoly(
   auto mono = ring.monoid().alloc();
   auto coef = ring.field().zero();
   do {
-    if (!p.isZero() && !in.peekSign())
+    if (!p.isZero() && !in.peekSign() && (!readComponent || in.peek() != '<'))
       in.expect('+', '-');
     readTerm(ring, readComponent, coef, mono, in);
     p.append(coef.value(), *mono);
@@ -403,13 +420,12 @@ void MathicIO<M, BF>::writePoly(
 
   const auto end = poly.end();
   for (auto it = poly.begin(); it != end; ++it) {
-    if (it != poly.begin())
-      out << '+';
     writeTerm(
       poly.ring(),
       writeComponent,
       poly.ring().field().toElement(it.coef()),
       it.mono(),
+      it != poly.begin(),
       out
     );
   }
@@ -449,10 +465,16 @@ template<class M, class BF>
 void MathicIO<M, BF>::writeTerm(
   const PolyRing& ring,
   const bool writeComponent,
-  const Coefficient coef,
+  Coefficient coef,
   ConstMonoRef mono,
+  bool writeSignEvenIfPositive,
   std::ostream& out
 ) {
+  if (ring.field().isNegative(coef)) {
+    out << "-";
+    coef = ring.field().negativeNonZero(coef);
+  } else if (writeSignEvenIfPositive)
+    out << '+';
   if (!ring.field().isOne(coef)) {
     out << unchar(coef.value());
     if (ring.monoid().isIdentity(mono)) {
@@ -481,7 +503,7 @@ void MathicIO<M, BF>::readMonomial(
       err << "Expected monomial, but got " << e << " (did you mean 1?).";
       in.reportError(err.str());
     }
-  } else {
+  } else if (!readComponent || in.peek() != '<') {
     bool sawSome = false;
     while (true) {
       const auto letterCount = 'z' - 'a' + 1;
diff --git a/src/mathicgb/Poly.cpp b/src/mathicgb/Poly.cpp
index 2d4b1af..5791ff8 100755
--- a/src/mathicgb/Poly.cpp
+++ b/src/mathicgb/Poly.cpp
@@ -3,19 +3,14 @@
 #include "stdinc.h"
 #include "Poly.hpp"
 
+#include "Range.hpp"
+#include "Zip.hpp"
 #include <ostream>
 #include <iostream>
 #include <algorithm>
 
 MATHICGB_NAMESPACE_BEGIN
 
-Poly& Poly::operator=(Poly&& poly) {
-  MATHICGB_ASSERT(&ring() == &poly.ring());
-  coeffs = std::move(poly.coeffs);
-  monoms = std::move(poly.monoms);
-  return *this;
-}
-
 void Poly::sortTermsDescending() {
   const size_t count = termCount();
   std::vector<size_t> ordered(count);
@@ -37,198 +32,45 @@ void Poly::sortTermsDescending() {
   MATHICGB_ASSERT(termsAreInDescendingOrder());
 }
 
-auto Poly::mono(size_t index) -> MonoRef {
-  MATHICGB_ASSERT(index < termCount());
-  return Monoid::toRef(&monoms[index * ring().maxMonomialSize()]);
-}
-
-auto Poly::mono(size_t index) const -> ConstMonoRef {
-  MATHICGB_ASSERT(index < termCount());
-  return Monoid::toRef(&monoms[index * ring().maxMonomialSize()]);
-}
-
-coefficient& Poly::coef(size_t index) {
-  MATHICGB_ASSERT(index < termCount());
-  return coeffs[index];
-}
-
-coefficient Poly::coef(size_t index) const {
-  MATHICGB_ASSERT(index < termCount());
-  return coeffs[index];
-}
-
-bool Poly::isMonic() const {
-  return !isZero() && ring().coefficientIsOne(leadCoef());
-}
-
 void Poly::makeMonic() {
-  if (isZero())
-    return;
-  coefficient c = leadCoef();
-  if (ring().coefficientIsOne(c))
+  MATHICGB_ASSERT(!isZero());
+  if (isMonic())
     return;
-  ring().coefficientReciprocalTo(c);
-  for (auto i = coeffs.begin(); i != coeffs.end(); i++)
-    ring().coefficientMultTo(*i, c);
-  MATHICGB_ASSERT(ring().coefficientIsOne(leadCoef()));
+  auto multiply = leadCoef();
+  ring().coefficientReciprocalTo(multiply);
+  for (auto& coef : mCoefs)
+    ring().coefficientMultTo(coef, multiply);
+  MATHICGB_ASSERT(isMonic());
 }
 
-bool operator==(const Poly &a, const Poly &b)
-{
-  if (&a.ring() != &b.ring())
-    return false;
+bool operator==(const Poly& a, const Poly& b) {
+  MATHICGB_ASSERT(&a.ring() == &b.ring());
   if (a.termCount() != b.termCount())
     return false;
-  const auto& ring = a.ring();
-  auto a1 = a.begin();
-  auto b1 = b.begin();
-  for (; a1 != a.end(); ++a1, ++b1) {
-    if (a1.coef() != b1.coef())
-      return false;
-    if (!ring.monoid().equal(a1.mono(), b1.mono()))
-      return false;
-  }
-  return true;
-}
-
-const_monomial Poly::backMono() const {
-  MATHICGB_ASSERT(begin() != end());
-  return &(monoms.front()) + ring().maxMonomialSize() * (termCount() - 1);
-}
-
-void Poly::parseDoNotOrder(std::istream& i)
-{
-  if (i.peek() == '0') {
-    i.get();
-    return;
-  }
-
-  while (true) {
-    bool preceededByMinus = false;
-    char next = i.peek();
-    if (next == '+') {
-      i.get();
-      next = i.peek();
-    } else if (next == '-') {
-      preceededByMinus = true;
-      i.get();
-      next = i.peek();
-    }
 
-    if (!isdigit(next) && !isalpha(next) && next != '<')
-      break;
-    
-    { // read coefficient
-      int64 bigCoef = 1;
-      if (isdigit(next)) {
-        i >> bigCoef;
-        next = i.peek();
-      }
-      if (preceededByMinus)
-        bigCoef = -bigCoef;
-      coeffs.push_back(ring().toCoefficient(bigCoef));
-    }
-
-    // read monic monomial
-    const size_t firstLocation = monoms.size();
-    monoms.resize(firstLocation + ring().maxMonomialSize());
-    monomial m = &monoms[firstLocation];
-    if (isalpha(next) || next == '<')
-      ring().monomialParse(i, m);
-    else
-      ring().monomialSetIdentity(m); // have to do this to set hash value
-    next = i.peek();
-    if (next == '>')
-      i.get();
-  }
-}
-
-void Poly::parse(std::istream& in) {
-  parseDoNotOrder(in);
-  sortTermsDescending();
-}
-
-void Poly::display(std::ostream& out, const bool printComponent) const
-{
-  const auto p = ring().charac();
-  const auto maxPositive = (p + 1) / 2; // half rounded up
-  if (isZero()) {
-    out << "0";
-    return;
-  }
-  
-  for (auto i = begin(); i != end(); ++i) {
-    auto coef = i.coef();
-    if (coef > maxPositive) {
-      out << "-";
-      ring().coefficientNegateTo(coef);
-    } else if (i != begin())
-      out << '+';
-    if (coef != 1)
-      out << coef;
-    ring().monomialDisplay(out, Monoid::toOld(i.mono()), printComponent, coef == 1);
-  }
-}
+  for (const auto& coef : zip(a.coefRange(), b.coefRange()))
+    if (coef.first != coef.second)
+      return false;
 
-void Poly::display(FILE* file, bool printComponent) const
-{
-  if (isZero()) {
-    fputs("0", file);
-    return;
-  }
+  const auto& monoid = a.ring().monoid();
+  for (const auto& mono : zip(a.monoRange(), b.monoRange()))
+    if (!monoid.equal(mono.first, mono.second))
+      return false;
 
-  const auto characteristic = ring().charac();
-  const auto maxPositiveCoefficient = (characteristic + 1) / 2;
-  bool firstTerm = true;
-  for (auto it = begin(); it != end(); ++it) {
-      auto coef = it.coef();
-      if (coef > maxPositiveCoefficient) {
-        coef = characteristic - coef;
-        fputc('-', file);
-      } else if (!firstTerm)
-        fputc('+', file);
-      bool printOne = true;
-      if (coef != 1) {
-        printOne = false;
-        fprintf(file, "%li", (long)coef);
-      }
-      ring().monomialDisplay(file, Monoid::toOld(it.mono()), printComponent, printOne);
-      firstTerm = false;
-    }
+  return true;
 }
 
 size_t Poly::getMemoryUse() const {
   size_t total = sizeof(const PolyRing *);
-  total += sizeof(coefficient) * coeffs.capacity();
-  total += sizeof(int) * monoms.capacity();
+  total += sizeof(coefficient) * mCoefs.capacity();
+  total += sizeof(int) * mMonos.capacity();
   return total;
 }
 
-void Poly::setToZero() {
-  coeffs.clear();
-  monoms.clear();
-}
-
-void Poly::see(bool print_comp) const
-{
-  display(std::cout, print_comp);
-  std::cout << std::endl;
-}
-
-std::ostream& operator<<(std::ostream& out, const Poly& p) {
-  p.see(false);
-  return out;
-}
-
-void Poly::reserve(size_t spaceForThisManyTerms) {
-  monoms.reserve(spaceForThisManyTerms * ring().maxMonomialSize());
-}
-
 bool Poly::termsAreInDescendingOrder() const {
   if (!isZero()) {
     auto prev = leadMono().ptr();
-    MonoRange range = {++monoBegin(), monoEnd()};
-    for (const auto& mono : range) {
+    for (const auto& mono : range(++monoBegin(), monoEnd())) {
       if (monoid().lessThan(*prev, mono))
         return false;
       prev = mono.ptr();
diff --git a/src/mathicgb/Poly.hpp b/src/mathicgb/Poly.hpp
index 1f53554..942ccf2 100755
--- a/src/mathicgb/Poly.hpp
+++ b/src/mathicgb/Poly.hpp
@@ -4,6 +4,8 @@
 #define MATHICGB_POLY_GUARD
 
 #include "PolyRing.hpp"
+#include "Range.hpp"
+#include "Zip.hpp"
 #include <vector>
 #include <ostream>
 #include <utility>
@@ -23,161 +25,212 @@ public:
 
   Poly(const PolyRing& ring): mRing(ring) {}
 
-  void parse(std::istream &i); // reads into this, sorts terms
-  void parseDoNotOrder(std::istream &i); // reads into this, does not sort terms
-  void display(FILE* file, bool printComponent = true) const;
-  void display(std::ostream& out, bool printComponent = true) const;
-  void see(bool print_comp) const;
+  Poly(const Poly& poly):
+    mRing(poly.ring()), mCoefs(poly.mCoefs), mMonos(poly.mMonos)
+  {}
 
-  class const_iterator {
-  public:
-    typedef std::random_access_iterator_tag iterator_category;
-    typedef std::pair<const coefficient, const const_monomial> value_type;
-    typedef ptrdiff_t difference_type;
-    typedef value_type* pointer; // todo: is this OK?
-    typedef std::pair<const coefficient&, const const_monomial> reference;
+  Poly(const Poly&& poly):
+    mRing(poly.ring()),
+    mCoefs(std::move(poly.mCoefs)),
+    mMonos(std::move(poly.mMonos))
+  {}
 
-    const_iterator() {}
-    const_iterator& operator++() { ++ic; im += monsize; return *this; }
+  const PolyRing& ring() const {return mRing;}
+  const Monoid& monoid() const {return ring().monoid();}
+  bool isZero() const {return mCoefs.empty();}
+  size_t termCount() const {return mCoefs.size();}
+  size_t getMemoryUse() const;
 
-    coefficient coef() const {return *ic;}
-    ConstMonoRef mono() const {return Monoid::toRef(&*im);}
+  /// Orders terms in descending order.
+  void sortTermsDescending();
 
-    friend bool operator==(const const_iterator &a, const const_iterator &b);
-    friend bool operator!=(const const_iterator &a, const const_iterator &b);
+  /// Appends the given term as the last term in the polynomial.
+  void append(coefficient coef, ConstMonoRef mono);
 
-    NewConstTerm operator*() const {
-      NewConstTerm t = {coef(), mono()};
-      return t;
-    }
+  /// Hint that space for the give number of terms is going to be needed.
+  /// This serves the same purpose as std::vector<>::reserve.
+  void reserve(size_t spaceForThisManyTerms) {
+    mMonos.reserve(spaceForThisManyTerms * monoid().entryCount());
+  }
 
-  private:
-    size_t monsize;
-    std::vector<coefficient>::const_iterator ic;
-    std::vector<exponent>::const_iterator im;
-    friend class Poly;
+  /// Makes the polynomial monic by multiplying by the multiplicative inverse
+  /// of leadCoef(). Calling this method is an error if isZero().
+  void makeMonic();
 
-    const_iterator(const Poly& f) : monsize(f.ring().maxMonomialSize()), ic(f.coeffs.begin()), im(f.monoms.begin()) {}
-    const_iterator(const Poly& f,int) : ic(f.coeffs.end()), im() {}
-  };
+  void setToZero() {
+    mCoefs.clear();
+    mMonos.clear();
+  }
 
-  const_iterator begin() const { return const_iterator(*this); }
-  const_iterator end() const { return const_iterator(*this,1); }
+  Poly& operator=(const Poly& poly) {return *this = Poly(poly);}
+  Poly& operator=(Poly&& poly) {
+    MATHICGB_ASSERT(&ring() == &poly.ring());
+    mCoefs = std::move(poly.mCoefs);
+    mMonos = std::move(poly.mMonos);
+    return *this;
+  }
 
-  class MonoIterator {
-    size_t monsize;
-    std::vector<coefficient>::const_iterator ic;
-    std::vector<exponent>::const_iterator im;
-    friend class Poly;
 
-    MonoIterator(const Poly& f) : monsize(f.ring().maxMonomialSize()), ic(f.coeffs.begin()), im(f.monoms.begin()) {}
-    MonoIterator(const Poly& f,int) : ic(f.coeffs.end()), im(f.monoms.end()) {}
+  // *** Accessing the coefficients of the terms in the polynomial.
 
+  /// Returns the coefficient of the given term.
+  coefficient coef(size_t index) const {
+    MATHICGB_ASSERT(index < termCount());
+    return mCoefs[index];
+  }
+
+  /// Returns the coefficient of the leading term.
+  coefficient leadCoef() const {
+    MATHICGB_ASSERT(!isZero());
+    return coef(0);
+  }
+
+  /// Returns true if the polynomial is monic. A polynomial is monic if
+  /// the coefficient of the leading monomial is 1. If you are asking this
+  /// question about a polynomial, that likely means that you are expecting
+  /// the polynomial not to be zero. So it is an error to ask if the zero
+  /// polynomial is monic - you'll get an assert to help pinpoint the error.
+  bool isMonic() const {
+    MATHICGB_ASSERT(!isZero());
+    return ring().coefficientIsOne(leadCoef());
+  }
+
+  typedef std::vector<coefficient>::const_iterator ConstCoefIterator;
+  typedef Range<ConstCoefIterator> ConstCoefIteratorRange;
+
+  ConstCoefIterator coefBegin() const {return mCoefs.begin();}
+  ConstCoefIterator coefEnd() const {return mCoefs.end();}
+  ConstCoefIteratorRange coefRange() const {
+    return range(coefBegin(), coefEnd());
+  }
+
+
+  // *** Accessing the monomials of the terms in the polynomial
+
+  /// Returns the monomial of the given term.
+  ConstMonoRef mono(size_t index) const {
+    MATHICGB_ASSERT(index < termCount());
+    return Monoid::toRef(&mMonos[index * monoid().entryCount()]);
+  }
+
+  /// Returns the monomial of the leading term.
+  ConstMonoRef leadMono() const {
+    MATHICGB_ASSERT(!isZero());
+    return mono(0);
+  }
+
+  /// Returns the monomial of the last term.
+  ConstMonoRef backMono() const {
+    MATHICGB_ASSERT(!isZero());
+    return mono(termCount() - 1);
+  }
+
+  /// Returns true if the terms are in descending order. The terms are in
+  /// descending order when mono(0) >= mono(1) >= ... >= backMono.
+  bool termsAreInDescendingOrder() const;
+
+  class ConstMonoIterator {
   public:
     typedef std::forward_iterator_tag iterator_category;
     typedef ConstMonoRef value_type;
-    typedef ptrdiff_t difference_type;
     typedef value_type* pointer;
     typedef ConstMonoRef reference;
 
-    MonoIterator() {}
-    MonoIterator operator++() { ++ic; im += monsize; return *this; }
-    bool operator==(const MonoIterator& it) const {return im == it.im;}
-    bool operator!=(const MonoIterator& it) const {return im != it.im;}
-    const value_type operator*() const {return Monoid::toRef(&*im);}
-  };
+    ConstMonoIterator() {}
 
-  MonoIterator monoBegin() const { return MonoIterator(*this); }
-  MonoIterator monoEnd() const { return MonoIterator(*this,1); }
-  struct MonoRange {
-    MonoIterator mBegin;
-    const MonoIterator mEnd;
-    MonoIterator begin() {return mBegin;}
-    MonoIterator end() {return mEnd;}
-  };
-  MonoRange monoRange() const {
-    MonoRange range = {monoBegin(), monoEnd()};
-    return range;
-  }
+    ConstMonoIterator& operator++() {
+      mIt += mEntryCount;
+      return *this;
+    }
 
-  /// Orders terms in descending order.
-  void sortTermsDescending();
+    ConstMonoRef operator*() const {return Monoid::toRef(&*mIt);}
 
-  /// Returns the coefficient of the given term.
-  coefficient& coef(size_t index);
+    bool operator==(const ConstMonoIterator& it) const {return mIt == it.mIt;}
+    bool operator!=(const ConstMonoIterator& it) const {return mIt != it.mIt;}
 
-  /// Returns the coefficient of the given term.
-  coefficient coef(size_t index) const;
+  private:
+    friend class Poly;
+    typedef std::vector<exponent>::const_iterator Iterator;
 
-  /// Returns the monomial of the given term.
-  MonoRef mono(size_t index);
+    ConstMonoIterator(const Monoid& monoid, Iterator it):
+      mEntryCount(monoid.entryCount()),
+      mIt(it)
+    {}
 
-  /// Returns the monomial of the given term.
-  ConstMonoRef mono(size_t index) const;
+    size_t mEntryCount;
+    Iterator mIt;
+  };
 
-  /// Returns the coefficient of the leading term.
-  coefficient leadCoef() const {return coef(0);}
+  typedef Range<ConstMonoIterator> ConstMonoIteratorRange;
 
-  /// Returns the monomial of the leading term.
-  ConstMonoRef leadMono() const {return mono(0);}
+  ConstMonoIterator monoBegin() const {
+    return ConstMonoIterator(monoid(), mMonos.begin());
+  }
 
-  /// Returns the monomial of the last term.
-  const_monomial backMono() const;
+  ConstMonoIterator monoEnd() const {
+    return ConstMonoIterator(monoid(), mMonos.end());
+  }
 
-  /// Appends the given term as the last term in the polynomial.
-  void append(coefficient coef, ConstMonoRef mono);
+  ConstMonoIteratorRange monoRange() const {
+    return range(monoBegin(), monoEnd());
+  }
 
-  /// Hint that space for termCount terms is going to be needed. This serves
-  /// the same purpose as std::vector<>::reserve.
-  void reserve(size_t termCount);
 
-  const coefficient* coefficientBegin() const {return coeffs.data();}
+  // *** Iteration through terms
 
-  void makeMonic();
-  bool isMonic() const;
+  class ConstTermIterator {
+  public:
+    typedef std::forward_iterator_tag iterator_category;
+    typedef NewConstTerm value_type;
 
-  bool isZero() const { return coeffs.empty(); }
+    ConstTermIterator() {}
 
-  size_t termCount() const {return coeffs.size();}
+    ConstTermIterator& operator++() {
+      ++mIt;
+      return *this;
+    }
 
-  size_t getMemoryUse() const;
+    value_type operator*() const {
+      auto pair = *mIt;
+      NewConstTerm term = {pair.first, pair.second};
+      return term;
+    }
 
-  void setToZero();
+    bool operator==(const ConstTermIterator& it) const {return mIt == it.mIt;}
+    bool operator!=(const ConstTermIterator& it) const {return mIt != it.mIt;}
 
-  Poly& operator=(const Poly& poly) {return *this = Poly(poly);}
-  Poly& operator=(Poly&& poly);
+    coefficient coef() const {return (*mIt).first;}
+    ConstMonoRef mono() const {return (*mIt).second;}
 
-  friend bool operator==(const Poly &a, const Poly &b);
+  private:
+    friend class Poly;
+    typedef Zip<ConstCoefIterator, ConstMonoIterator> Iterator;
+    ConstTermIterator(const Iterator& it): mIt(it) {}
 
-  const PolyRing& ring() const {return mRing;}
-  const Monoid& monoid() const {return ring().monoid();}
+    Iterator mIt;
+  };
 
-  bool termsAreInDescendingOrder() const;
+  typedef Range<ConstTermIterator> ConstTermIteratorRange;
+
+  ConstTermIterator begin() const {return makeZip(coefBegin(), monoBegin());}
+  ConstTermIterator end() const {return makeZip(coefEnd(), monoEnd());}
+  ConstTermIteratorRange termRange() const {return range(begin(), end());}
 
 private:
+  friend bool operator==(const Poly &a, const Poly &b);
+
   const PolyRing& mRing;
-  std::vector<coefficient> coeffs;
-  std::vector<exponent> monoms;
+  std::vector<coefficient> mCoefs;
+  std::vector<exponent> mMonos;
 };
 
-std::ostream& operator<<(std::ostream& out, const Poly& p);
-
-inline bool operator==(const Poly::const_iterator &a, const Poly::const_iterator &b)
-{
-  return a.ic == b.ic;
-}
-inline bool operator!=(const Poly::const_iterator &a, const Poly::const_iterator &b)
-{
-  return a.ic != b.ic;
-}
-
+// This is inline since it is performance-critical.
 inline void Poly::append(coefficient a, ConstMonoRef m) {
-  coeffs.push_back(a);
-  size_t len = ring().maxMonomialSize();
-  auto& monoid = ring().monoid();
-  const auto offset = monoms.size();
-  monoms.resize(offset + monoid.entryCount());
-  monoid.copy(m, *PolyRing::Monoid::MonoPtr(monoms.data() + offset));
+  mCoefs.push_back(a);
+
+  const auto offset = mMonos.size();
+  mMonos.resize(offset + monoid().entryCount());
+  monoid().copy(m, *PolyRing::Monoid::MonoPtr(mMonos.data() + offset));
 }
 
 MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/PrimeField.hpp b/src/mathicgb/PrimeField.hpp
index 58a88ef..03fd228 100755
--- a/src/mathicgb/PrimeField.hpp
+++ b/src/mathicgb/PrimeField.hpp
@@ -50,6 +50,13 @@ public:
   bool isZero(const Element a) const {return a == zero();}
   bool isOne(const Element a) const {return a == one();}
 
+  /// Returns true if a is strictly in the upper half of the range of values.
+  /// These can be considered as a negative number with smaller absolute
+  /// value, which can be useful for example when printing the value.
+  bool isNegative(const Element a) const {
+    return a.value() > (charac() + 1) / 2;
+  }
+
   T charac() const {return mCharac;}
 
   /// Assumes that i is in the range [0;charac()).
diff --git a/src/mathicgb/Range.hpp b/src/mathicgb/Range.hpp
new file mode 100644
index 0000000..39d6c83
--- /dev/null
+++ b/src/mathicgb/Range.hpp
@@ -0,0 +1,44 @@
+// MathicGB copyright 2012 all rights reserved. MathicGB comes with ABSOLUTELY
+// NO WARRANTY and is licensed as GPL v2.0 or later - see LICENSE.txt.
+#ifndef MATHICGB_RANGE_GUARD
+#define MATHICGB_RANGE_GUARD
+
+#include <utility>
+
+MATHICGB_NAMESPACE_BEGIN
+
+/// An object that combines two iterators into a range suitable for use with
+/// C++11's range for. It is most conveniently used with the function range.
+/// For example:
+///
+///  std::vector<int> v;
+///  for (int x : range(v.begin(), v.end()) {}
+///
+/// std::vector already has begin and end members, so range() is not necessary
+/// here. range() is useful when a class does not have begin or end members, or
+/// if it offers several different ranges that can be iterated through -
+/// then the default range can only offer one of those ranges.
+template<class Iterator>
+class Range {
+public:
+  Range(Iterator begin, Iterator end): mBegin(begin), mEnd(end) {}
+  Range(std::pair<Iterator, Iterator> pair):
+    mBegin(pair.first), mEnd(pair.second) {}
+
+  Iterator begin() {return mBegin;}
+  Iterator end() {return mBegin;}
+
+private:
+  Iterator mBegin;
+  Iterator mEnd;
+};
+
+/// Convenience function for constructing a Range object.
+template<class Iterator>
+Range<Iterator> range(Iterator begin, Iterator end) {
+  return Range<Iterator>(begin, end);
+}
+
+MATHICGB_NAMESPACE_END
+
+#endif
diff --git a/src/mathicgb/ReducerHashPack.cpp b/src/mathicgb/ReducerHashPack.cpp
index 1606cf1..8898e75 100644
--- a/src/mathicgb/ReducerHashPack.cpp
+++ b/src/mathicgb/ReducerHashPack.cpp
@@ -54,8 +54,8 @@ private:
   struct MultipleWithPos {
     MultipleWithPos(const Poly& poly, NewConstTerm multiple);
 
-    Poly::const_iterator pos;
-    Poly::const_iterator const end;
+    Poly::ConstTermIterator pos;
+    const Poly::ConstTermIterator end;
     NewTerm multiple;
     PolyHashTable::Node* node;
 
diff --git a/src/mathicgb/ReducerPack.cpp b/src/mathicgb/ReducerPack.cpp
index 99a245f..5bed3c8 100644
--- a/src/mathicgb/ReducerPack.cpp
+++ b/src/mathicgb/ReducerPack.cpp
@@ -55,8 +55,8 @@ private:
   struct MultipleWithPos {
     MultipleWithPos(const Poly& poly, NewConstTerm multiple);
 
-    Poly::const_iterator pos;
-    Poly::const_iterator const end;
+    Poly::ConstTermIterator pos;
+    const Poly::ConstTermIterator end;
     NewTerm multiple;
 
     // invariant: current is the monomial product of multiple.monom 
diff --git a/src/mathicgb/ReducerPackDedup.cpp b/src/mathicgb/ReducerPackDedup.cpp
index 74cada2..86dc53f 100644
--- a/src/mathicgb/ReducerPackDedup.cpp
+++ b/src/mathicgb/ReducerPackDedup.cpp
@@ -50,8 +50,8 @@ private:
   struct MultipleWithPos {
     MultipleWithPos(const Poly& poly, NewConstTerm multiple);
 
-    Poly::const_iterator pos;
-    Poly::const_iterator const end;
+    Poly::ConstTermIterator pos;
+    const Poly::ConstTermIterator end;
     NewTerm multiple;
 
     // invariant: current is the monomial product of multiple.monom 
diff --git a/src/mathicgb/SigPolyBasis.cpp b/src/mathicgb/SigPolyBasis.cpp
index 1d40719..90a96c2 100755
--- a/src/mathicgb/SigPolyBasis.cpp
+++ b/src/mathicgb/SigPolyBasis.cpp
@@ -384,7 +384,7 @@ void SigPolyBasis::display(std::ostream& out) const {
     else
       MathicIO<>().writeMonomial(monoid(), true, *mSignatures[i], out);
     out << "  ";
-    mBasis.poly(i).display(out, false);
+    MathicIO<>().writePoly(mBasis.poly(i), false, out);
     out << '\n';
   }
 }
@@ -411,7 +411,7 @@ void SigPolyBasis::displayFancy
       MathicIO<>().writeMonomial(monoid(), true, *sig, out);
     sigOut << '\n';
 
-    mBasis.poly(i).display(polyOut, false);
+    MathicIO<>().writePoly(mBasis.poly(i), false, polyOut);
     polyOut << '\n';
   }
   out << pr;
diff --git a/src/mathicgb/TypicalReducer.cpp b/src/mathicgb/TypicalReducer.cpp
index 9a11701..a0bdc87 100755
--- a/src/mathicgb/TypicalReducer.cpp
+++ b/src/mathicgb/TypicalReducer.cpp
@@ -5,6 +5,7 @@
 
 #include "SigPolyBasis.hpp"
 #include "PolyBasis.hpp"
+#include "MathicIO.hpp"
 #include <iostream>
 
 MATHICGB_NAMESPACE_BEGIN
@@ -73,7 +74,8 @@ std::unique_ptr<Poly> TypicalReducer::regularReduce(
       insertTail(const_term(coef, mon), &basis.poly(reducer));
     }
   }
-  result->makeMonic();
+  if (!result->isZero())
+    result->makeMonic();
 
   reset();
   return result;
@@ -199,7 +201,7 @@ std::unique_ptr<Poly> TypicalReducer::classicReduce
 
       if (tracingLevel > 100) {
         std::cerr << "Reducing by basis element " << reducer << ": ";
-        basis.poly(reducer).display(std::cerr);
+        MathicIO<>().writePoly(basis.poly(reducer), false, std::cerr);
         std::cerr << std::endl;
         std::cerr << "multiplied by: " << coef << "  *  ";
         basis.ring().monomialDisplay(std::cerr, mon);
@@ -207,7 +209,8 @@ std::unique_ptr<Poly> TypicalReducer::classicReduce
       }
     }
   }
-  result->makeMonic();
+  if (!result->isZero())
+    result->makeMonic();
 
   if (tracingLevel > 100)
     std::cerr << "Classic reduction done." << std::endl;
diff --git a/src/mathicgb/io-util.cpp b/src/mathicgb/io-util.cpp
index 33936e9..c3bd81e 100755
--- a/src/mathicgb/io-util.cpp
+++ b/src/mathicgb/io-util.cpp
@@ -21,16 +21,15 @@ MATHICGB_NAMESPACE_BEGIN
 
 std::unique_ptr<Poly> polyParseFromString(const PolyRing *R, const std::string &s)
 {
-  std::unique_ptr<Poly> f(new Poly(*R));
   std::istringstream in(s);
-  f->parse(in);
-  return f;
+  Scanner scanner(in);
+  return make_unique<Poly>(MathicIO<>().readPoly(*R, false, scanner));
 }
 
 std::string toString(const Poly *g)
 {
   std::ostringstream o;
-  g->display(o);
+  MathicIO<>().writePoly(*g, true, o);
   return o.str();
 }
 
@@ -88,7 +87,7 @@ std::string toString(SigPolyBasis *I)
   for (size_t i=0; i<I->size(); i++)
     {
       o << "  ";
-      I->poly(i).display(o, false);
+      MathicIO<>().writePoly(I->poly(i), false, o);
       o << std::endl;
     }
   return o.str();
@@ -114,7 +113,7 @@ std::string toString(Basis *I)
   for (size_t i=0; i<I->size(); i++)
     {
       o << "  ";
-      I->getPoly(i)->display(o,false);
+      MathicIO<>().writePoly(*I->getPoly(i), false, o);
       o << std::endl;
     }
   return o.str();
@@ -126,22 +125,10 @@ void output(std::ostream &o, const PolyBasis &I)
     {
       if (!I.retired(i))
         {
-          I.poly(i).display(o, false);
+          MathicIO<>().writePoly(I.poly(i), false, o);
           o << std::endl;
         }
     }
 }
 
-void output(FILE* file, const PolyBasis &I)
-{
-  for (size_t i = 0; i < I.size(); i++)
-    {
-      if (!I.retired(i))
-        {
-          I.poly(i).display(file, false);
-          fputc('\n', file);
-        }
-    }
-}
-
 MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/io-util.hpp b/src/mathicgb/io-util.hpp
index 15f71be..4442c20 100755
--- a/src/mathicgb/io-util.hpp
+++ b/src/mathicgb/io-util.hpp
@@ -33,7 +33,6 @@ std::unique_ptr<Poly> polyParseFromString
   (const PolyRing *R, const std::string &s);
 
 void output(std::ostream &o, const PolyBasis &I);
-void output(FILE* file, const PolyBasis &I);
 
 MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/test/F4MatrixBuilder.cpp b/src/test/F4MatrixBuilder.cpp
index f502298..474aba8 100755
--- a/src/test/F4MatrixBuilder.cpp
+++ b/src/test/F4MatrixBuilder.cpp
@@ -9,7 +9,7 @@
 #include "mathicgb/PolyBasis.hpp"
 #include "mathicgb/io-util.hpp"
 #include "mathicgb/mtbb.hpp"
-
+#include "mathicgb/MathicIO.hpp"
 #include <gtest/gtest.h>
 #include <memory>
 
@@ -32,9 +32,10 @@ namespace {
     {}
 
     const Poly& addBasisElement(const std::string& str) {
-      std::unique_ptr<Poly> p(new Poly(*mRing));
       std::istringstream in(str);
-      p->parse(in);
+      Scanner scanner(in);
+      auto p = make_unique<Poly>
+        (MathicIO<>().readPoly(*mRing, false, scanner));
       mBasis.insert(std::move(p));
       return mBasis.poly(mBasis.size() - 1);
     }
@@ -124,23 +125,25 @@ TEST(F4MatrixBuilder, OneByOne) {
 TEST(F4MatrixBuilder, DirectReducers) {
   for (int threadCount = 1; threadCount < 4; ++threadCount) {
     BuilderMaker maker;
-    maker.addBasisElement("a6<0>"); // reducer == to lead term
-    maker.addBasisElement("a3b2<0>+a3c"); // reducer == to lower order term
-    maker.addBasisElement("c<0>"); // reducer divides
-    maker.addBasisElement("d2<0>"); // does not divide
+    maker.addBasisElement("a6"); // reducer == to lead term
+    maker.addBasisElement("a3b2+a3c"); // reducer == to lower order term
+    maker.addBasisElement("c"); // reducer divides
+    maker.addBasisElement("d2"); // does not divide
     F4MatrixBuilder& builder = maker.create();
 
     Poly p1(builder.ring());
     { 
-      std::istringstream in("a3<0>+b2+c+d");
-      p1.parse(in);
+      std::istringstream in("a3+b2+c+d");
+      Scanner scanner(in);
+      p1 = MathicIO<>().readPoly(builder.ring(), false, scanner);
       builder.addPolynomialToMatrix(p1.leadMono(), p1);
     }
 
     Poly p2(builder.ring());
     {
-      std::istringstream in("a3<0>+2b2+3c+4d");
-      p2.parse(in);
+      std::istringstream in("a3+2b2+3c+4d");
+      Scanner scanner(in);
+      p2 = MathicIO<>().readPoly(builder.ring(), false, scanner);
       builder.addPolynomialToMatrix(p2.leadMono(), p2);
     }
 
diff --git a/src/test/F4MatrixReducer.cpp b/src/test/F4MatrixReducer.cpp
index bd53a3f..135b438 100755
--- a/src/test/F4MatrixReducer.cpp
+++ b/src/test/F4MatrixReducer.cpp
@@ -7,6 +7,7 @@
 #include "mathicgb/QuadMatrix.hpp"
 #include "mathicgb/io-util.hpp"
 #include "mathicgb/Poly.hpp"
+#include "mathicgb/MathicIO.hpp"
 #include <gtest/gtest.h>
 #include <sstream>
 
@@ -16,9 +17,9 @@ TEST(F4MatrixReducer, Reduce) {
   auto ring = ringFromString("101 6 1\n10 1 1 1 1 1");
   QuadMatrix m(*ring);
 
-  Poly p(*ring);
   std::istringstream in("a4+a3+a2+a1+b5+b4+b3+b2+b1");
-  p.parse(in);
+  Scanner scanner(in);
+  auto p = MathicIO<>().readPoly(*ring, false, scanner);
   size_t count = 0;
   for (auto it = p.begin(); it != p.end(); ++it) {
     if (count < 4)
diff --git a/src/test/MathicIO.cpp b/src/test/MathicIO.cpp
index 5e65def..44b3f69 100755
--- a/src/test/MathicIO.cpp
+++ b/src/test/MathicIO.cpp
@@ -175,7 +175,7 @@ TEST(MathicIO, ReadWritePoly) {
         continue;
 
       Scanner in(str);
-      const auto poly = MathicIO<>().readPoly(ring, doComponent, in);
+      const auto poly = MathicIO<>().readPolyDoNotOrder(ring, doComponent, in);
       std::ostringstream out;
       MathicIO<>().writePoly(poly, doComponent, out);
       const auto correctStr = outStr == 0 ? inStr : outStr;
@@ -230,14 +230,15 @@ TEST(MathicIO, ReadWriteTerm) {
 
       // print monomial
       std::ostringstream out;
-      MathicIO<>().writeTerm(ring, doComponent, readCoef, *monoRead, out);
+      MathicIO<>().writeTerm
+        (ring, doComponent, readCoef, *monoRead, false, out);
       const auto correctStr = outStr == 0 ? inStr : outStr;
       ASSERT_EQ(correctStr, out.str());
     }
   };
 
   check("1", 0, false, 1);
-  check("-1", "100", false, f.minusOne().value());
+  check("-1", "-1", false, f.minusOne().value());
   check("+1", "1", false, 1);
   check("2", 0, false, 2);
   check("+102", "1", false, 1);
@@ -246,7 +247,7 @@ TEST(MathicIO, ReadWriteTerm) {
   check("+1<2>", "1<2>", true, 1);
   check("2<3>", 0, true, 2);
   check("+3<4>", "3<4>", true, 3);
-  check("-3<4>", "98<4>", true, f.negative(f.toElement(3)).value());
+  check("-3<4>", "-3<4>", true, f.negative(f.toElement(3)).value());
 
   check("+1a<0>", "a<0>", true, 1);
   check("+2b", "2b", false, 2);
diff --git a/src/test/QuadMatrixBuilder.cpp b/src/test/QuadMatrixBuilder.cpp
index 7bf57f5..f0d035d 100755
--- a/src/test/QuadMatrixBuilder.cpp
+++ b/src/test/QuadMatrixBuilder.cpp
@@ -34,9 +34,9 @@ namespace {
   {
     const PolyRing& ring = b.ring();
     {
-      Poly p(b.ring());
       std::istringstream in(left);
-      p.parseDoNotOrder(in);
+      Scanner scanner(in);
+      auto p = MathicIO<>().readPolyDoNotOrder(ring, true, scanner);
       size_t colCount = 0;
       for (auto it = p.begin(); it != p.end(); ++it) {
         QuadMatrixBuilder::LeftRightColIndex lrCol =
@@ -50,9 +50,9 @@ namespace {
       }
     }
     {
-      Poly p(b.ring());
       std::istringstream in(right);
-      p.parseDoNotOrder(in);
+      Scanner scanner(in);
+      auto p = MathicIO<>().readPolyDoNotOrder(ring, true, scanner);
       size_t colCount = 0;
       for (auto it = p.begin(); it != p.end(); ++it) {
         QuadMatrixBuilder::LeftRightColIndex lrCol =
@@ -138,11 +138,11 @@ TEST(QuadMatrixBuilder, ColumnQuery) {
   QuadMatrixBuilder b(*ring, map, monoLeft, monoRight);
   createColumns("a<1>+<0>", "b<0>+c<0>+bc<0>", b);
 
-  Poly p(b.ring());
   // coefficient 1X=left, 2X=right, 30=not there, % 10 = column index
   std::istringstream in
     ("10a<1>+11<0>+20b<0>+21c<0>+22bc<0>+30ab<0>+30e<0>+10a<1>");
-  p.parseDoNotOrder(in);
+  Scanner scanner(in);
+  auto p = MathicIO<>().readPolyDoNotOrder(b.ring(), true, scanner);
   for (auto it = p.begin(); it != p.end(); ++it) {
     const QuadMatrixBuilder::LeftRightColIndex* col =
       MonomialMap<QuadMatrixBuilder::LeftRightColIndex>::Reader(map).
diff --git a/src/test/SparseMatrix.cpp b/src/test/SparseMatrix.cpp
index b0b961f..3f1a921 100755
--- a/src/test/SparseMatrix.cpp
+++ b/src/test/SparseMatrix.cpp
@@ -6,6 +6,7 @@
 #include "mathicgb/Poly.hpp"
 #include "mathicgb/PolyRing.hpp"
 #include "mathicgb/io-util.hpp"
+#include "mathicgb/MathicIO.hpp"
 #include <gtest/gtest.h>
 #include <memory>
 #include <string>
@@ -14,10 +15,9 @@ using namespace mgb;
 
 namespace {
   std::unique_ptr<Poly> parsePoly(const PolyRing& ring, std::string str) {
-    auto p = make_unique<Poly>(ring);
     std::istringstream in(str);
-    p->parse(in);
-    return p;
+    Scanner scanner(in);
+    return make_unique<Poly>(MathicIO<>().readPoly(ring, false, scanner));
   }
 }
 
diff --git a/src/test/poly-test.cpp b/src/test/poly-test.cpp
index ec11eee..a8449c5 100755
--- a/src/test/poly-test.cpp
+++ b/src/test/poly-test.cpp
@@ -8,6 +8,7 @@
 #include "mathicgb/io-util.hpp"
 #include "mathicgb/SigPolyBasis.hpp"
 #include "mathicgb/SignatureGB.hpp"
+#include "mathicgb/MathicIO.hpp"
 #include <gtest/gtest.h>
 #include <cstdio>
 #include <string>
@@ -36,25 +37,14 @@ a2c2d-b2d3 \
 c3d3-b2d4 \
 ";
 
-TEST(Poly,readwrite) {
-  std::string f1 = "14ce2<72>+13adf<16>";
-  std::unique_ptr<PolyRing> R(ringFromString("32003 6 1\n1 1 1 1 1 1"));
-  Poly f(*R);
-  std::stringstream ifil(f1);
-  f.parseDoNotOrder(ifil);
-  std::ostringstream o;
-  f.display(o,true);
-  EXPECT_EQ(o.str(), f1);
-}
-
-bool testPolyParse(PolyRing* R, std::string s)
+bool testPolyParse(PolyRing* R, std::string s, bool withComponent)
 {
   // parse poly, then see if it matches the orig string
-  Poly f(*R);
   std::istringstream i(s);
-  f.parseDoNotOrder(i);
+  Scanner in(i);
+  auto f = MathicIO<>().readPolyDoNotOrder(*R, withComponent, in);
   std::ostringstream o;
-  f.display(o);
+  MathicIO<>().writePoly(f, withComponent, o);
   //  std::cout << "orig = " << s << std::endl;
   //  std::cout << "f    = " << o.str() << std::endl;
   return o.str() == s;
@@ -62,11 +52,11 @@ bool testPolyParse(PolyRing* R, std::string s)
 bool testPolyParse2(PolyRing* R, std::string s, std::string answer)
 {
   // parse poly, then see if it matches the orig string
-  Poly f(*R);
   std::istringstream i(s);
-  f.parseDoNotOrder(i);
+  Scanner scanner(i);
+  auto f = MathicIO<>().readPolyDoNotOrder(*R, false, scanner);
   std::ostringstream o;
-  f.display(o);
+  MathicIO<>().writePoly(f, false, o);
   //  std::cout << "orig = " << s << std::endl;
   //  std::cout << "f    = " << o.str() << std::endl;
   return o.str() == answer;
@@ -75,9 +65,10 @@ bool testPolyParse2(PolyRing* R, std::string s, std::string answer)
 TEST(Poly,parse) {
   std::unique_ptr<PolyRing> R(ringFromString("32003 6 1\n1 1 1 1 1 1"));
 
-  EXPECT_TRUE(testPolyParse(R.get(), "3a<1>+<0>"));
-  EXPECT_TRUE(testPolyParse(R.get(), "3a<1>+13af3<0>+14cde<0>"));
-  EXPECT_TRUE(testPolyParse(R.get(), "<1>+13af3<0>+14cde<0>"));
+  EXPECT_TRUE(testPolyParse(R.get(), "3a<1>+1<0>", true));
+  EXPECT_TRUE(testPolyParse(R.get(), "3a+1", false));
+  EXPECT_TRUE(testPolyParse(R.get(), "3a<1>+13af3<0>+14cde<0>", true));
+  EXPECT_TRUE(testPolyParse(R.get(), "1<1>+13af3<0>+14cde<0>", true));
 }
 
 bool testMonomialParse(PolyRing* R, std::string s)
@@ -624,11 +615,10 @@ TEST(Ideal,readwrite) {
     {
       const Poly *f = I->getPoly(i);
       std::ostringstream o;
-      f->display(o,false);
-      Poly g(f->ring());
+      MathicIO<>().writePoly(*f, false, o);
       std::stringstream ifil(o.str());
-      g.parse(ifil);
-      EXPECT_TRUE(g == *f);
+      Scanner scanner(ifil);
+      EXPECT_TRUE(MathicIO<>().readPoly(f->ring(), false, scanner) == *f);
     }
 }
 

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