[mathicgb] 380/393: Poly::assign can now accept a range and the implementation of Poly::polyWithTermsDescending is now a bit simpler - there are no loops in there any more and what is sorted is no longer a set of pairs (term, index) pairs since the index was not being used anymore anyway.

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 a921b987d76ea4526bf6262bda6266821e3400fd
Author: Bjarke Hammersholt Roune <http://www.broune.com/>
Date:   Sun Sep 22 00:33:55 2013 +0200

    Poly::assign can now accept a range and the implementation of Poly::polyWithTermsDescending is now a bit simpler - there are no loops in there any more and what is sorted is no longer a set of pairs (term, index) pairs since the index was not being used anymore anyway.
---
 src/mathicgb/Poly.cpp | 50 ++++++++++++++++++++++++--------------------------
 src/mathicgb/Poly.hpp | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 26 deletions(-)

diff --git a/src/mathicgb/Poly.cpp b/src/mathicgb/Poly.cpp
index 9352499..6a6f097 100755
--- a/src/mathicgb/Poly.cpp
+++ b/src/mathicgb/Poly.cpp
@@ -8,25 +8,23 @@
 MATHICGB_NAMESPACE_BEGIN
 
 Poly Poly::polyWithTermsDescending() {
-  // *** Sort (term, index) pairs in descending order of monomial.
-  // Grr, if only C++11 lambda's allowed auto in the parameter list,
-  // then it would not have been necessary to ever mention the type
-  // Entry. But alas, that won't be here until C++14.
-  typedef std::pair<NewConstTerm, size_t> Entry;
-  auto greaterThan = [&](const Entry& a, const Entry& b) {
-    return monoid().lessThan(*b.first.mono, *a.first.mono);
+  // *** Sort terms in descending order of monomial.
+  // It would be possible but cumbersome to implement a sort directly
+  // on mMonos. That way no allocation would need to happen, however
+  // 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.
+  auto greaterOrEqual = [&](const NewConstTerm& a, const NewConstTerm& b) {
+    return monoid().lessThan(*b.mono, *a.mono);
   };
-  auto ordered = rangeToVector(indexRange(*this));
-  std::sort(std::begin(ordered), std::end(ordered), greaterThan);
+  auto terms = rangeToVector(*this);
+  std::sort(std::begin(terms), std::end(terms), greaterOrEqual);
 
   // *** Make a new polynomial with terms in that order
   Poly poly(ring());
-  poly.reserve(termCount());
-  for (const auto& p : ordered)
-    poly.append(p.first);
+  poly.append(terms, termCount());
 
   MATHICGB_ASSERT(poly.termsAreInDescendingOrder());
-  MATHICGB_ASSERT(termCount() == poly.termCount());
 
   // This return statements causes no copy. The return value optimization
   // will be used at the option of the compiler. If a crappy compiler gets
@@ -68,6 +66,19 @@ void Poly::makeMonic() {
   MATHICGB_ASSERT(isMonic());
 }
 
+size_t Poly::getMemoryUse() const {
+  return 
+    sizeof(mCoefs.front()) * mCoefs.capacity() +
+    sizeof(mMonos.front()) * mMonos.capacity();
+}
+
+bool Poly::termsAreInDescendingOrder() const {
+  auto greaterThanOrEqual = [&](ConstMonoRef a, ConstMonoRef b) {
+    return !monoid().lessThan(a, b);
+  };
+  return std::is_sorted(monoBegin(), monoEnd(), greaterThanOrEqual);
+}
+
 bool operator==(const Poly& a, const Poly& b) {
   MATHICGB_ASSERT(&a.ring() == &b.ring());
   if (a.termCount() != b.termCount())
@@ -85,17 +96,4 @@ bool operator==(const Poly& a, const Poly& b) {
   return true;
 }
 
-size_t Poly::getMemoryUse() const {
-  return 
-    sizeof(mCoefs.front()) * mCoefs.capacity() +
-    sizeof(mMonos.front()) * mMonos.capacity();
-}
-
-bool Poly::termsAreInDescendingOrder() const {
-  auto greaterThanOrEqual = [&](ConstMonoRef a, ConstMonoRef b) {
-    return !monoid().lessThan(a, b);
-  };
-  return std::is_sorted(monoBegin(), monoEnd(), greaterThanOrEqual);
-}
-
 MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/Poly.hpp b/src/mathicgb/Poly.hpp
index 26d77d8..1a2400f 100755
--- a/src/mathicgb/Poly.hpp
+++ b/src/mathicgb/Poly.hpp
@@ -22,6 +22,7 @@ public:
   typedef Monoid::MonoPtr MonoPtr;
   typedef Monoid::ConstMonoPtr ConstMonoPtr;
 
+  /// Constructs the zero polynomial in the given ring.
   Poly(const PolyRing& ring): mRing(ring) {}
 
   Poly(const Poly& poly):
@@ -58,6 +59,35 @@ public:
     append(term.coef, *term.mono);
   }
 
+  /// Appends each term in the range r to the end of the polynomial.
+  /// 
+  template<class Range>
+  void append(const Range& r) {
+    for (const auto& term : r)
+      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(
+    const ForwardIterator& termsBegin,
+    const ForwardIterator& termsEnd
+  ) {
+    append(range(termsBegin, termsEnd));
+  }
+
+
   void append(coefficient coef, ConstMonoRef mono);
 
   /// Hint that space for the give number of terms is going to be needed.
@@ -246,6 +276,8 @@ private:
   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) {
   mCoefs.push_back(a);

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