[mathicgb] 381/393: Made Poly use PolyRing::Field and other slight cleanup.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:37 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 f42b685402b70b49f807b5ebb0bfbe7d927423d6
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Mon Sep 23 12:49:25 2013 +0200

    Made Poly use PolyRing::Field and other slight cleanup.
---
 src/mathicgb/F4MatrixBuilder.cpp  | 10 ++++-----
 src/mathicgb/F4MatrixBuilder.hpp  |  5 ++++-
 src/mathicgb/F4MatrixBuilder2.cpp | 11 ++++++----
 src/mathicgb/F4MatrixBuilder2.hpp |  5 ++++-
 src/mathicgb/MathicIO.hpp         |  2 +-
 src/mathicgb/Poly.cpp             | 41 +++++++++-------------------------
 src/mathicgb/Poly.hpp             | 39 ++++++++++++++++-----------------
 src/mathicgb/PolyRing.hpp         | 10 ++++++---
 src/mathicgb/PrimeField.hpp       | 46 +++++++++++++++++++++++++++++++++++----
 src/mathicgb/Scanner.hpp          |  3 ++-
 src/mathicgb/SigPolyBasis.cpp     |  2 +-
 src/mathicgb/SigPolyBasis.hpp     |  3 +++
 12 files changed, 105 insertions(+), 72 deletions(-)

diff --git a/src/mathicgb/F4MatrixBuilder.cpp b/src/mathicgb/F4MatrixBuilder.cpp
index 7f932d7..b970be8 100755
--- a/src/mathicgb/F4MatrixBuilder.cpp
+++ b/src/mathicgb/F4MatrixBuilder.cpp
@@ -296,9 +296,9 @@ updateReader:
     }
 
     const auto origScalar = it.coef();
-    MATHICGB_ASSERT(origScalar != 0);
+    MATHICGB_ASSERT(!ring().field().isZero(origScalar));
     const auto maybeNegated =
-      negate ? ring().coefficientNegateNonZero(origScalar) : origScalar;
+      negate ? field().negativeNonZero(origScalar) : origScalar;
 	MATHICGB_ASSERT(maybeNegated < std::numeric_limits<Scalar>::max());
     builder.appendEntryBottom(*col.first, static_cast<Scalar>(maybeNegated));
   }
@@ -330,14 +330,14 @@ updateReader:
   ColReader colMap(mMap);
   while (it != end) {
 	MATHICGB_ASSERT(it.coef() < std::numeric_limits<Scalar>::max());
-    MATHICGB_ASSERT(it.coef() != 0);
+    MATHICGB_ASSERT(!field().isZero(it.coef()));
     const auto scalar1 = static_cast<Scalar>(it.coef());
     const auto mono1 = it.mono();
 
     auto it2 = it;
     ++it2;
 	MATHICGB_ASSERT(it2.coef() < std::numeric_limits<Scalar>::max());
-    MATHICGB_ASSERT(it2.coef() != 0);
+    MATHICGB_ASSERT(!field().isZero(it2.coef()));
     const auto scalar2 = static_cast<Scalar>(it2.coef());
     const auto mono2 = it2.mono();
 
@@ -410,7 +410,7 @@ void F4MatrixBuilder::appendRowBottom(
       ++itB;
     }
     MATHICGB_ASSERT(coeff < std::numeric_limits<Scalar>::max());
-    if (coeff != 0)
+    if (!field().isZero(coeff))
       builder.appendEntryBottom(col, static_cast<Scalar>(coeff));
   }
 }
diff --git a/src/mathicgb/F4MatrixBuilder.hpp b/src/mathicgb/F4MatrixBuilder.hpp
index 0d4d384..f43c658 100755
--- a/src/mathicgb/F4MatrixBuilder.hpp
+++ b/src/mathicgb/F4MatrixBuilder.hpp
@@ -29,6 +29,8 @@ private:
   typedef QuadMatrixBuilder::Monomials Monomials;
 
 public:
+  typedef PolyRing::Field Field;
+
   typedef PolyRing::Monoid Monoid;
   typedef Monoid::Mono Mono;
   typedef Monoid::MonoRef MonoRef;
@@ -78,7 +80,8 @@ public:
   void buildMatrixAndClear(QuadMatrix& matrix);
 
   const PolyRing& ring() const {return mBuilder.ring();}
-  const Monoid& monoid() const {return mBuilder.ring().monoid();}
+  const Monoid& monoid() const {return ring().monoid();}
+  const Field& field() const {return ring().field();}
 
 private:
   typedef const MonomialMap<LeftRightColIndex>::Reader ColReader;
diff --git a/src/mathicgb/F4MatrixBuilder2.cpp b/src/mathicgb/F4MatrixBuilder2.cpp
index 87e9bad..b475de9 100755
--- a/src/mathicgb/F4MatrixBuilder2.cpp
+++ b/src/mathicgb/F4MatrixBuilder2.cpp
@@ -20,6 +20,8 @@ MATHICGB_NAMESPACE_BEGIN
 
 class F4MatrixBuilder2::Builder {
 public:
+  typedef PolyRing::Field Field;
+
   typedef PolyRing::Monoid Monoid;
   typedef Monoid::Mono Mono;
   typedef Monoid::MonoRef MonoRef;
@@ -264,7 +266,8 @@ public:
   }
 
   const PolyRing& ring() const {return mBasis.ring();}
-  const Monoid& monoid() const {return mBasis.ring().monoid();}
+  const Monoid& monoid() const {return ring().monoid();}
+  const Field& field() const {return ring().field();}
 
     Builder(const PolyBasis& basis, const size_t memoryQuantum):
     mMemoryQuantum(memoryQuantum),
@@ -358,7 +361,7 @@ public:
       const auto col = findOrCreateColumn
         (it.mono(), multiple, reader, feeder);
 	  MATHICGB_ASSERT(it.coef() < std::numeric_limits<Scalar>::max());
-      MATHICGB_ASSERT(it.coef() != 0);
+      MATHICGB_ASSERT(!field().isZero(it.coef()));
       *indices = col.first;
       ++indices;
       ++it;
@@ -367,14 +370,14 @@ public:
     ColReader colMap(mMap);
     while (it != end) {
 	  MATHICGB_ASSERT(it.coef() < std::numeric_limits<Scalar>::max());
-      MATHICGB_ASSERT(it.coef() != 0);
+      MATHICGB_ASSERT(!field().isZero(it.coef()));
       const auto scalar1 = static_cast<Scalar>(it.coef());
       const auto mono1 = it.mono();
 
       auto it2 = it;
       ++it2;
 	  MATHICGB_ASSERT(it2.coef() < std::numeric_limits<Scalar>::max());
-      MATHICGB_ASSERT(it2.coef() != 0);
+      MATHICGB_ASSERT(!field().isZero(it2.coef()));
       const auto scalar2 = static_cast<Scalar>(it2.coef());
       const auto mono2 = it2.mono();
 
diff --git a/src/mathicgb/F4MatrixBuilder2.hpp b/src/mathicgb/F4MatrixBuilder2.hpp
index 06ac20b..46c3c71 100755
--- a/src/mathicgb/F4MatrixBuilder2.hpp
+++ b/src/mathicgb/F4MatrixBuilder2.hpp
@@ -22,6 +22,8 @@ MATHICGB_NAMESPACE_BEGIN
 /// functionality, so add one of those before fixing this.
 class F4MatrixBuilder2 {
 public:
+  typedef PolyRing::Field Field;
+
   typedef PolyRing::Monoid Monoid;
   typedef Monoid::Mono Mono;
   typedef Monoid::MonoRef MonoRef;
@@ -72,7 +74,8 @@ public:
   void buildMatrixAndClear(QuadMatrix& matrix);
 
   const PolyRing& ring() const {return mBasis.ring();}
-  const Monoid& monoid() const {return mBasis.ring().monoid();}
+  const Monoid& monoid() const {return ring().monoid();}
+  const Field& field() const {return ring().field();}
 
 private:
   /// Represents the task of adding a row to the matrix. If sPairPoly is null
diff --git a/src/mathicgb/MathicIO.hpp b/src/mathicgb/MathicIO.hpp
index 1ec1709..998a8fd 100755
--- a/src/mathicgb/MathicIO.hpp
+++ b/src/mathicgb/MathicIO.hpp
@@ -421,7 +421,7 @@ void MathicIO<M, BF>::writePoly(
     writeTerm(
       poly.ring(),
       writeComponent,
-      poly.ring().field().toElement(it.coef()),
+      it.coef(),
       it.mono(),
       it != poly.begin(),
       out
diff --git a/src/mathicgb/Poly.cpp b/src/mathicgb/Poly.cpp
index 6a6f097..fe84c9a 100755
--- a/src/mathicgb/Poly.cpp
+++ b/src/mathicgb/Poly.cpp
@@ -14,6 +14,11 @@ Poly Poly::polyWithTermsDescending() {
   // it is not clear that that would be any faster, since swapping around
   // monomials in-place is slow. Swapping terms is faster, since terms
   // just refer to the monomials. This way is also easier to implement.
+  //
+  /// @todo: make a separate TermSorter object that allows the terms vector
+  /// to be reused between sorts. This should matter for sorting input
+  /// ideals where there might be a lot of polynomials to go through.
+  /// That way terms would not need to be allocated anew for each polynomial.
   auto greaterOrEqual = [&](const NewConstTerm& a, const NewConstTerm& b) {
     return monoid().lessThan(*b.mono, *a.mono);
   };
@@ -22,36 +27,11 @@ Poly Poly::polyWithTermsDescending() {
 
   // *** Make a new polynomial with terms in that order
   Poly poly(ring());
-  poly.append(terms, termCount());
+  poly.reserve(termCount());
+  poly.append(terms);
 
   MATHICGB_ASSERT(poly.termsAreInDescendingOrder());
-
-  // This return statements causes no copy. The return value optimization
-  // will be used at the option of the compiler. If a crappy compiler gets
-  // that wrong, poly will be treated as an r-value, which is to say that
-  // this code becomes equivalent to return std::move(poly). That happens
-  // because poly is a local variable being returned, so the standard
-  // allows movement out of poly in this particular situation - that is
-  // safe/reasonable because the very next thing that will happen to poly is
-  // that it will get destructed, so anyone in a position to know that the
-  // contents of poly had been moved out would then also be using
-  // a pointer to the now-invalid poly object, which invokes undefined
-  // behavior anyway.
-  //
-  // Capturing the returned Poly into another poly also will not cause a copy.
-  // Consider the code
-  //
-  //   Poly p1(q.polyWithTermsDescending());
-  //   Poly p2(ring);
-  //   p2 = q.polyWithTermsDescending();
-  //   
-  // The return value is an unnamed temporary that is constructed/assigned
-  // into p1/p2. Unnamed temporaries are r-values, so the guts of those
-  // temporary objects will be moved into p1/p2. There will be no copy.
-  //
-  // (Of course there is the one copy that we are doing further up into poly
-  // to avoid doing an in-place sort. The point is that there are no further
-  // copies than that one.)
+  MATHICGB_ASSERT(poly.termCount() == termCount());
   return poly;
 }
 
@@ -59,10 +39,9 @@ void Poly::makeMonic() {
   MATHICGB_ASSERT(!isZero());
   if (isMonic())
     return;
-  auto multiply = leadCoef();
-  ring().coefficientReciprocalTo(multiply);
+  auto multiplier = field().inverse(leadCoef());
   for (auto& coef : mCoefs)
-    ring().coefficientMultTo(coef, multiply);
+    coef = field().product(coef, multiplier);
   MATHICGB_ASSERT(isMonic());
 }
 
diff --git a/src/mathicgb/Poly.hpp b/src/mathicgb/Poly.hpp
index 1a2400f..2b19cb5 100755
--- a/src/mathicgb/Poly.hpp
+++ b/src/mathicgb/Poly.hpp
@@ -15,6 +15,10 @@ MATHICGB_NAMESPACE_BEGIN
 
 class Poly {
 public:
+  typedef PolyRing::Field Field;
+  typedef Field::Element Coef;
+  typedef Field::ConstElementRef ConstCoefRef;
+
   typedef PolyRing::Monoid Monoid;
   typedef Monoid::Mono Mono;
   typedef Monoid::MonoRef MonoRef;
@@ -37,6 +41,8 @@ public:
 
   const PolyRing& ring() const {return mRing;}
   const Monoid& monoid() const {return ring().monoid();}
+  const Field& field() const {return ring().field();}
+
   bool isZero() const {return mCoefs.empty();}
   size_t termCount() const {return mCoefs.size();}
   size_t getMemoryUse() const;
@@ -56,6 +62,11 @@ public:
   /// Appends the given term as the last term in the polynomial.
   void append(const NewConstTerm& term) {
     MATHICGB_ASSERT(term.mono != nullptr);
+    typedef Field::RawElement C;
+    typedef Field::Element E;
+    C c = term.coef;
+    E e = c;
+
     append(term.coef, *term.mono);
   }
 
@@ -67,17 +78,6 @@ public:
       append(term);
   }
 
-  /// As append(r), but possibly with better performance. The number of
-  /// elements in the range r must equal rangeTermCount.
-  template<class Range>
-  void append(const Range& r, size_t rangeTermCount) {
-    MATHICGB_ASSERT
-      (std::distance(std::begin(r), std::end(r)) == rangeTermCount);
-    reserve(termCount() + rangeTermCount);
-    for (const auto& term : r)
-      append(term);
-  }
-
   /// As append(range(termsBegin, termsEnd))
   template<class ForwardIterator>
   void append(
@@ -87,8 +87,7 @@ public:
     append(range(termsBegin, termsEnd));
   }
 
-
-  void append(coefficient coef, ConstMonoRef mono);
+  void append(ConstCoefRef coef, ConstMonoRef mono);
 
   /// Hint that space for the give number of terms is going to be needed.
   /// This serves the same purpose as std::vector<>::reserve.
@@ -117,13 +116,13 @@ public:
   // *** Accessing the coefficients of the terms in the polynomial.
 
   /// Returns the coefficient of the given term.
-  coefficient coef(size_t index) const {
+  const Coef& coef(size_t index) const {
     MATHICGB_ASSERT(index < termCount());
     return mCoefs[index];
   }
 
   /// Returns the coefficient of the leading term.
-  coefficient leadCoef() const {
+  const Coef& leadCoef() const {
     MATHICGB_ASSERT(!isZero());
     return mCoefs.front();
   }
@@ -135,10 +134,10 @@ public:
   /// polynomial is monic - you'll get an assert to help pinpoint the error.
   bool isMonic() const {
     MATHICGB_ASSERT(!isZero());
-    return ring().coefficientIsOne(leadCoef());
+    return field().isOne(leadCoef());
   }
 
-  typedef std::vector<coefficient>::const_iterator ConstCoefIterator;
+  typedef std::vector<Coef>::const_iterator ConstCoefIterator;
   typedef Range<ConstCoefIterator> ConstCoefIteratorRange;
 
   ConstCoefIterator coefBegin() const {return mCoefs.begin();}
@@ -246,7 +245,7 @@ public:
     bool operator==(const ConstTermIterator& it) const {return mIt == it.mIt;}
     bool operator!=(const ConstTermIterator& it) const {return mIt != it.mIt;}
 
-    coefficient coef() const {return (*mIt).first;}
+    const Coef& coef() const {return (*mIt).first;}
     ConstMonoRef mono() const {return (*mIt).second;}
 
   private:
@@ -272,14 +271,14 @@ private:
   friend bool operator==(const Poly &a, const Poly &b);
 
   const PolyRing& mRing;
-  std::vector<coefficient> mCoefs;
+  std::vector<Coef> mCoefs;
   std::vector<exponent> mMonos;
 };
 
 bool operator==(const Poly& a, const Poly& b);
 
 // This is inline since it is performance-critical.
-inline void Poly::append(coefficient a, ConstMonoRef m) {
+inline void Poly::append(ConstCoefRef a, ConstMonoRef m) {
   mCoefs.push_back(a);
 
   const auto offset = mMonos.size();
diff --git a/src/mathicgb/PolyRing.hpp b/src/mathicgb/PolyRing.hpp
index 54e6907..97140cc 100755
--- a/src/mathicgb/PolyRing.hpp
+++ b/src/mathicgb/PolyRing.hpp
@@ -91,7 +91,9 @@ typedef int32 exponent ;
 typedef uint32 HashValue;
 typedef long coefficient;
 typedef MonoMonoid<exponent> Monoid;
-typedef PrimeField<unsigned long> Field;
+
+/// This typedef should really be for an unsigned type.
+typedef PrimeField<coefficient> Field;
 
 
 typedef exponent* vecmonomial; // includes a component
@@ -231,7 +233,9 @@ struct term {
 class PolyRing {
 public:
   typedef MonoMonoid<exponent> Monoid;
-  typedef PrimeField<unsigned long> Field;
+
+  /// This typedef should really be for an unsigned type.
+  typedef PrimeField<coefficient> Field;
 
   /// @todo: make this dependent on the monoid and field once all code
   /// has been migrated from ::term to PolyRing::Term.
@@ -499,7 +503,7 @@ public:
   ///////////////////////////////////////////
 
   const Monoid& monoid() const {return mMonoid;}
-  const Field field() const {return mField;}
+  const Field& field() const {return mField;}
 
 private:
   Field mField;
diff --git a/src/mathicgb/PrimeField.hpp b/src/mathicgb/PrimeField.hpp
index 03fd228..a486752 100755
--- a/src/mathicgb/PrimeField.hpp
+++ b/src/mathicgb/PrimeField.hpp
@@ -19,9 +19,31 @@ public:
 
   class Element {
   public:
-    static_assert(!std::numeric_limits<T>::is_signed, "");
+    // Re-instate this assert once all code has moved to using PrimeField
+    // properly so that coefficients are no longer signed.
+    //static_assert(!std::numeric_limits<T>::is_signed, "");
     static_assert(std::numeric_limits<T>::is_integer, "");
 
+    /// This constructor/conversion needs to go away as soon as all code
+    /// has been converted to using PrimeField properly. Kill it with fire!
+    Element(const RawElement& e): mValue(e) {}
+
+    /// This conversion needs to go away as soon as all code
+    /// has been converted to using PrimeField properly. Kill it with fire!
+    operator RawElement&() {return mValue;}
+
+    /// This conversion needs to go away as soon as all code
+    /// has been converted to using PrimeField properly. Kill it with fire!
+    operator const RawElement&() const {return mValue;}
+
+    /// This method needs to go away as soon as all code
+    /// has been converted to using PrimeField properly. Kill it with fire!
+    bool operator==(const RawElement e) const {return value() == e.value();}
+
+    /// This method needs to go away as soon as all code
+    /// has been converted to using PrimeField properly. Kill it with fire!
+    bool operator!=(const RawElement e) const {return !(*this == e);}
+
     Element(const Element& e): mValue(e.value()) {}
 
     Element& operator=(const Element& e) {
@@ -31,16 +53,23 @@ public:
 
     bool operator==(const Element e) const {return value() == e.value();}
     bool operator!=(const Element e) const {return !(*this == e);}
+
     T value() const {return mValue;}
 
   private:
     friend class PrimeField;
-    Element(const T value): mValue(value) {}
+    // Uncomment this constructor once the public one is gone.
+    //Element(const T value): mValue(value) {}
 
     friend class PrimeFile;
     T mValue;
   };
 
+  typedef Element& ElementRef;
+  typedef const Element& ConstElementRef;
+  typedef Element* ElementPtr;
+  typedef const Element* ConstElementPtr;
+
   PrimeField(const T primeCharacteristic): mCharac(primeCharacteristic) {}
 
   Element zero() const {return Element(0);}
@@ -67,7 +96,10 @@ public:
 
     MATHICGB_ASSERT(0 <= i);
     typedef typename std::make_unsigned<NoRefInteger>::type Unsigned;
-    MATHICGB_ASSERT(static_cast<Unsigned>(i) < charac());
+    //replace the below assert with this uncommented one once we get rid
+    //of signed element types.
+    //MATHICGB_ASSERT(static_cast<Unsigned>(i) < charac());
+    MATHICGB_ASSERT(i < charac());
     return Element(i);
   }
 
@@ -167,11 +199,17 @@ namespace PrimeFieldInternal {
   template<> struct ModularProdType<uint16> {typedef uint32 type;};
   template<> struct ModularProdType<uint32> {typedef uint64 type;};
 
+  template<> struct ModularProdType<int8> {typedef int16 type;};
+  template<> struct ModularProdType<int16> {typedef int32 type;};
+  template<> struct ModularProdType<int32> {typedef int64 type;};
+
   // @todo: Remove this typedef when possible. 64 bits is not enough
   // to store a 64 bit product. We need it right now because
   // coefficients are handled as 64 bit in the legacy PolyRing.
   template<> struct ModularProdType<uint64> {typedef uint64 type;};
   template<> struct ModularProdType<long unsigned int> {typedef uint64 type;};
+  template<> struct ModularProdType<int64> {typedef uint64 type;};
+  template<> struct ModularProdType<long int> {typedef uint64 type;};
 }
 
 template<class T>
@@ -215,7 +253,7 @@ auto PrimeField<T>::inverse(const Element elementA) const -> Element {
 
     // second turn
     if (b == 1) {
-      MATHICGB_ASSERT(minusLastX != 0);
+      MATHICGB_ASSERT(!isZero(minusLastX));
       MATHICGB_ASSERT(minusLastX < charac());
       x = charac() - minusLastX;
       break;
diff --git a/src/mathicgb/Scanner.hpp b/src/mathicgb/Scanner.hpp
index 4c1af9d..b608832 100755
--- a/src/mathicgb/Scanner.hpp
+++ b/src/mathicgb/Scanner.hpp
@@ -255,7 +255,8 @@ typename PrimeField<T>::Element Scanner::readModular(
 
   // Otherwise we need to consider that the most negative value's
   // negative cannot be represented as a positive number when reading.
-  static_assert(!std::is_signed<T>::value, "");
+  // todo: reinstate this assert once we get rid of signed coefficients.
+  //static_assert(!std::is_signed<T>::value, "");
 
   eatWhite();
   const bool minus = !match('+') && match('-');
diff --git a/src/mathicgb/SigPolyBasis.cpp b/src/mathicgb/SigPolyBasis.cpp
index 90a96c2..fcef4bb 100755
--- a/src/mathicgb/SigPolyBasis.cpp
+++ b/src/mathicgb/SigPolyBasis.cpp
@@ -57,7 +57,7 @@ void SigPolyBasis::addComponent() {
 void SigPolyBasis::insert(Mono ownedSig, std::unique_ptr<Poly> f) {
   MATHICGB_ASSERT(f.get() != nullptr);
   MATHICGB_ASSERT(!f->isZero());
-  MATHICGB_ASSERT(f->leadCoef() != 0);
+  MATHICGB_ASSERT(!field().isZero(f->leadCoef()));
   MATHICGB_ASSERT(!ownedSig.isNull());
   MATHICGB_ASSERT(monoid().fromPool(*ownedSig));
 
diff --git a/src/mathicgb/SigPolyBasis.hpp b/src/mathicgb/SigPolyBasis.hpp
index 46d48ef..afbd7c6 100755
--- a/src/mathicgb/SigPolyBasis.hpp
+++ b/src/mathicgb/SigPolyBasis.hpp
@@ -21,6 +21,8 @@ MATHICGB_NAMESPACE_BEGIN
 /// use in signature Groebner basis algorithms.
 class SigPolyBasis {
 public:
+  typedef PolyRing::Field Field;
+
   typedef PolyRing::Monoid Monoid;
   typedef Monoid::Mono Mono;
   typedef Monoid::MonoRef MonoRef;
@@ -40,6 +42,7 @@ public:
 
   const PolyRing& ring() const {return mBasis.ring();}
   const Monoid& monoid() const {return ring().monoid();}
+  const Field& field() const {return ring().field();}
 
   const Poly& poly(size_t index) const {return mBasis.poly(index);}
   size_t size() const {return mBasis.size();}

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