[mathicgb] 346/393: Moved the implementation of the MonomialTableArray children to use StaticMonoLookup instead of implementation that functionality twice.

Doug Torrance dtorrance-guest at moszumanska.debian.org
Fri Apr 3 15:59:32 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 8c23210ed001fb2ab4e11cad9958b967d4c12fb8
Author: Bjarke Hammersholt Roune <bjarkehr.code at gmail.com>
Date:   Thu Aug 29 17:09:35 2013 +0200

    Moved the implementation of the MonomialTableArray children to use StaticMonoLookup instead of implementation that functionality twice.
---
 Makefile.am                                        |   1 -
 build/vs12/mathicgb-lib/mathicgb-lib.vcxproj       |   2 -
 .../vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters |   6 -
 src/mathicgb/MTArray.cpp                           | 284 ++++++++++----------
 src/mathicgb/MTArray.hpp                           |   2 +
 src/mathicgb/MonTableDivList.hpp                   | 285 --------------------
 src/mathicgb/MonTableKDTree.hpp                    | 290 ---------------------
 src/mathicgb/MonoLookup.cpp                        |  80 ++----
 src/mathicgb/MonoLookup.hpp                        |   1 -
 src/mathicgb/StaticMonoLookup.hpp                  | 169 ++++++++----
 src/test/poly-test.cpp                             |   2 -
 11 files changed, 280 insertions(+), 842 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 6964917..c70d33e 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -24,7 +24,6 @@ libmathicgb_la_SOURCES = src/mathicgb/BjarkeGeobucket2.cpp		\
   src/mathicgb/Basis.cpp src/mathicgb/Basis.hpp				\
   src/mathicgb/io-util.cpp src/mathicgb/io-util.hpp			\
   src/mathicgb/KoszulQueue.hpp src/mathicgb/MonomialHashTable.hpp	\
-  src/mathicgb/MonTableDivList.hpp src/mathicgb/MonTableKDTree.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				\
diff --git a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
index e2a0ca3..9183042 100755
--- a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
+++ b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj
@@ -508,8 +508,6 @@
     <ClInclude Include="..\..\..\src\mathicgb\MonoMonoid.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\MonoOrder.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\MonoProcessor.hpp" />
-    <ClInclude Include="..\..\..\src\mathicgb\MonTableDivList.hpp" />
-    <ClInclude Include="..\..\..\src\mathicgb\MonTableKDTree.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\MTArray.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\mtbb.hpp" />
     <ClInclude Include="..\..\..\src\mathicgb\NonCopyable.hpp" />
diff --git a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
index 201079b..0a7f127 100755
--- a/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
+++ b/build/vs12/mathicgb-lib/mathicgb-lib.vcxproj.filters
@@ -163,12 +163,6 @@
     <ClInclude Include="..\..\..\src\mathicgb\MonomialHashTable.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\src\mathicgb\MonTableDivList.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\..\src\mathicgb\MonTableKDTree.hpp">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\..\src\mathicgb\MTArray.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
diff --git a/src/mathicgb/MTArray.cpp b/src/mathicgb/MTArray.cpp
index e2b7276..3c888d4 100755
--- a/src/mathicgb/MTArray.cpp
+++ b/src/mathicgb/MTArray.cpp
@@ -3,142 +3,118 @@
 #include "stdinc.h"
 #include "MTArray.hpp"
 
-#include "MonTableKDTree.hpp"
-#include "MonTableDivList.hpp"
+#include "StaticMonoLookup.hpp"
+#include "MathicIO.hpp"
 
 MATHICGB_NAMESPACE_BEGIN
 
-template <typename MT>
-class MTArrayT : public MonomialTableArray
-{
-  typedef MT T;
-  typedef typename MT::Configuration Conf;
+template<
+  bool UseKDTree,
+  bool AllowRemovals,
+  bool UseDivMask
+>
+class ConcreteModuleMonoSet : public MonomialTableArray {
 public:
-  MTArrayT(size_t components, const Conf &conf):
-    R(conf.getPolyRing()), conf_(conf) {
-    for (size_t i = 0; i < components; ++i)
-      addComponent();
-  }
-
-  ~MTArrayT()
+  typedef PolyRing::Monoid Monoid;
+  struct NoData {};
+  typedef StaticMonoLookup<UseKDTree, NoData, AllowRemovals, UseDivMask>
+    Lookup;
+  typedef typename Lookup::Entry Entry;
+
+  ConcreteModuleMonoSet(const Monoid& monoid, const size_t componentCount):
+    mMonoid(monoid),
+    mComponentCount(componentCount),
+    mLookups(reinterpret_cast<Lookup*>(
+      new char[sizeof(Lookup) * componentCount]
+    ))
   {
-    for (size_t i = 0; i<tables.size(); i++)
-      delete tables[i];
+    for (size_t component = 0; component < componentCount; ++component)
+      new (&mLookups[component]) Lookup(monoid);
   }
 
-  Conf& getConfiguration() { return conf_; }
-  const Conf &getConfiguration() const { return conf_; }
-
-  bool insert(const_monomial m);
-  // Only inserts if minimal, in this case "true" is returned.
-  // and the object takes ownership of 'm'.
-
-  void addComponent() {tables.push_back(new T(conf_));}
-
-  bool member(const_monomial m);
-
-  virtual std::string name() const;
-
-  void display(std::ostream &o) const;
-
-  void getMonomials(std::vector<const_monomial>& monomials) const;
-  
-  size_t n_elems() const;
-
-  size_t getMemoryUse() const;
-private:
-  const PolyRing* R;
-  Conf conf_; // Used to create new instances of T.
-  std::vector<T *> tables;
-};
-
-template <typename MT>
-bool MTArrayT<MT>::insert(const_monomial m)
-{
-  size_t x = R->monomialGetComponent(m);
-  MATHICGB_ASSERT(x < tables.size());
-  MATHICGB_ASSERT(tables[x] != 0);
-  bool result = tables[x]->insert(m);
-  return result;
-}
+  virtual ~ConcreteModuleMonoSet() {
+    delete[] reinterpret_cast<char*>(mLookups);
+  }
 
-template <typename MT>
-bool MTArrayT<MT>::member(const_monomial m)
-{
-  size_t x = R->monomialGetComponent(m);
-  MATHICGB_ASSERT(x < tables.size());
-  MATHICGB_ASSERT(tables[x] != 0);
-  return tables[x]->member(m);
-}
+  virtual bool insert(const_monomial m) {
+    const auto c = monoid().component(m);
+    MATHICGB_ASSERT(c < componentCount());
+    if (member(m))
+      return false;
+    if (AllowRemovals)
+      mLookups[c].removeMultiples(m);
+    mLookups[c].insert(m, NoData());
+    return true;
+  }
 
-template <typename MT>
-void MTArrayT<MT>::getMonomials(std::vector<const_monomial>& monomials) const {
-  for (size_t i = 0; i < tables.size(); ++i)
-    tables[i]->getMonomials(monomials);  
-}
+  virtual bool member(const_monomial m) {
+    const auto c = monoid().component(m);
+    MATHICGB_ASSERT(c < componentCount());
+    return mLookups[c].divisor(m) != 0;
+  }
 
-template <typename MT>
-void MTArrayT<MT>::display(std::ostream &o) const
-{
-  class MonomialCompare {
-  public:
-    MonomialCompare(const PolyRing& ring): mRing(ring) {}
-    bool operator()(const_monomial a, const_monomial b) {
-      return mRing.monomialLT(a, b);
-    }
-  private:
-    const PolyRing& mRing;
-  };
+  virtual std::string name() const {
+    return Lookup(monoid()).getName();
+  }
 
-  std::vector<const_monomial> monomials;
-  for (size_t i=0; i<tables.size(); i++)
-    {
-      T *p = tables[i];
-      MATHICGB_ASSERT(p != 0);
-      if (p->n_elems() == 0)
+  virtual void display(std::ostream& out) const {
+    std::vector<const_monomial> monomials;
+    for (size_t c = 0; c < componentCount(); ++c) {
+      const Lookup& lookup = mLookups[c];
+      if (lookup.size() == 0)
         continue;
-
-      o << "  " << i << ": ";
+      out << "  " << c << ": ";
       monomials.clear();
-      p->getMonomials(monomials);
-      std::sort(monomials.begin(), monomials.end(), MonomialCompare(*R));
-      typedef std::vector<const_monomial>::const_iterator iter;
-      for (iter it = monomials.begin(); it != monomials.end(); ++it)
-        {
-          R->monomialDisplay(o, *it, false);
-          o << "  ";
-        }
-      o << '\n';
+      lookup.forAll([&](const Entry& entry) {
+        monomials.emplace_back(Monoid::toOld(entry.mono()));
+      });
+      const auto& monoid = this->monoid(); // workaround for gcc 4.5.3 issue
+      const auto cmp = [&](const_monomial a, const_monomial b) {
+        return monoid.lessThan(a, b);
+      };
+      std::sort(monomials.begin(), monomials.end(), cmp);
+      for (auto mono = monomials.cbegin(); mono != monomials.cend(); ++mono) {
+        MathicIO<>().writeMonomial(monoid, false, *mono, out);
+        out << "  ";
+      }
+      out << '\n';
     }
-}
+  }
 
-template <typename MT>
-size_t MTArrayT<MT>::n_elems() const
-{
-  size_t result = 0;
-  for (size_t i=0; i<tables.size(); i++)
-    if (tables[i] != 0)
-      result += tables[i]->n_elems();
-  return result;;
-}
+  virtual void getMonomials(std::vector<const_monomial>& monomials) const {
+    for (size_t c = 0; c < componentCount(); ++c) {
+      mLookups[c].forAll(
+        [&](const Entry& entry) {
+          monomials.push_back(Monoid::toOld(entry.mono()));
+        }
+      );
+    }
+  }
+  
+  virtual size_t n_elems() const {
+    size_t count = 0;
+    for (size_t c = 0; c < componentCount(); ++c)
+      count += mLookups[c].size();
+    return count;
+  }
 
-template <typename MT>
-size_t MTArrayT<MT>::getMemoryUse() const
-{
-  size_t sum = tables.capacity() * sizeof(tables.front());
-  for (size_t i = 0; i < tables.size(); ++i) {
-    MATHICGB_ASSERT(tables[i] != 0);
-    sum += sizeof(tables[i]) + tables[i]->getMemoryUse();
+  virtual size_t getMemoryUse() const {
+    size_t count = 0;
+    for (size_t c = 0; c < componentCount(); ++c)
+      count += mLookups[c].getMemoryUse();
+    return count;
   }
-  return sum;
-}
 
-template <typename MT>
-std::string MTArrayT<MT>::name() const
-{
-  T obj(getConfiguration());
-  return obj.getName();
-}
+  const Monoid& monoid() const {return mMonoid;}
+  size_t componentCount() const {return mComponentCount;}
+
+private:
+  const Monoid& mMonoid;
+
+  // We cannot use std::vector as Lookup might not be copyable or movable.
+  const size_t mComponentCount;
+  Lookup* const mLookups;
+};
 
 int MonomialTableArray::displayMTTypes(std::ostream &o)
  // returns n s.t. 0..n-1 are valid types
@@ -151,43 +127,45 @@ int MonomialTableArray::displayMTTypes(std::ostream &o)
   return 5;
 }
 
-std::unique_ptr<MonomialTableArray> MonomialTableArray::make(const PolyRing *R, int typ, size_t components, bool allowRemovals)
-{
-  switch (typ) {
-    case 1: {
-      typedef MonTableDivList<false,true> MT;
-      return make_unique<MTArrayT<MT>>(components, MT::Configuration
-        (R, true, false, true, .5, 500));
-    }
-    case 2: {
-      if (allowRemovals) {
-        typedef MonTableKDTree<true,true,1,true> MT;
-        return make_unique<MTArrayT<MT>>(components, MT::Configuration
-          (R, true, false, true, .5, 50));
-      } else {
-        typedef MonTableKDTree<true,true,1,false> MT;
-        return make_unique<MTArrayT<MT>>(components, MT::Configuration
-          (R, true, false, true, .5, 50));
-      }
-    }
-    case 3: {
-      typedef MonTableDivList<false,false> MT;
-      return make_unique<MTArrayT<MT>>(components, MT::Configuration
-        (R, true, false, true, .5, 500));
+namespace {
+  class ModuleMonoSetFactory {
+  public:
+    typedef PolyRing::Monoid Monoid;
+
+    std::unique_ptr<MonomialTableArray> create(
+      const Monoid& monoid,
+      int type,
+      size_t componentCount,
+      bool allowRemovals
+    ) {
+      const Params params = {monoid, type, componentCount};
+      return staticMonoLookupCreate
+        <Create, std::unique_ptr<MonomialTableArray>>
+        (type, allowRemovals, params);
     }
-    case 4: // fall through
-    default: {
-      if (allowRemovals) {
-        typedef MonTableKDTree<false,false,1,true> MT;
-        return make_unique<MTArrayT<MT>>(components, MT::Configuration
-          (R, true, false, true, .5, 50));
-      } else {
-        typedef MonTableKDTree<false,false,1,false> MT;
-        return make_unique<MTArrayT<MT>>(components, MT::Configuration
-          (R, true, false, true, .5, 50));
+
+  private:
+    struct Params {
+      const Monoid& monoid;
+      int type;
+      size_t componentCount;
+    };
+
+    template<bool UseKDTree, bool AllowRemovals, bool UseDivMask>
+    struct Create {
+      static std::unique_ptr<MonomialTableArray> create(const Params& params) {
+        return make_unique
+          <ConcreteModuleMonoSet<UseKDTree, AllowRemovals, UseDivMask>>
+          (params.monoid, params.componentCount);
       }
-    }
-  }
+    };
+  };
+}
+
+std::unique_ptr<MonomialTableArray> MonomialTableArray::make
+  (const PolyRing *R, int typ, size_t components, bool allowRemovals)
+{
+  return ModuleMonoSetFactory().create(R->monoid(), typ, components, allowRemovals);
 }
 
 MATHICGB_NAMESPACE_END
diff --git a/src/mathicgb/MTArray.hpp b/src/mathicgb/MTArray.hpp
index 8d7667d..5ab0f52 100755
--- a/src/mathicgb/MTArray.hpp
+++ b/src/mathicgb/MTArray.hpp
@@ -18,6 +18,8 @@ public:
   // returns true if the monomial actually needs to be inserted.
   // If the monomial is inserted, the caller agrees to keep that monomial
   // active until it is removed from the table.
+  // Only inserts if minimal, in this case "true" is returned.
+  // and the object takes ownership of 'm'.
   virtual bool insert(const_monomial m) = 0;
 
   virtual bool member(const_monomial m) = 0;
diff --git a/src/mathicgb/MonTableDivList.hpp b/src/mathicgb/MonTableDivList.hpp
deleted file mode 100755
index d159074..0000000
--- a/src/mathicgb/MonTableDivList.hpp
+++ /dev/null
@@ -1,285 +0,0 @@
-// 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_MON_TABLE_DIV_LIST_GUARD
-#define MATHICGB_MON_TABLE_DIV_LIST_GUARD
-
-#include "PolyRing.hpp"
-#include <string>
-#include <vector>
-#include <iostream>
-#include <mathic.h>
-
-MATHICGB_NAMESPACE_BEGIN
-
-/** Helper class for MonTableDivList. */
-template<bool UseLinkedList, bool UseDivMask>
-class MonTableDivListConfiguration;
-
-template<bool ULL, bool UDM>
-class MonTableDivListConfiguration {
-public:
-  typedef int Exponent;
-  typedef const_monomial Monomial;
-  typedef Monomial Entry;
-
-  MonTableDivListConfiguration
-  (const PolyRing *R0,
-   bool minimizeOnInsert,
-   bool moveDivisorToFront,
-   bool sortOnInsert,
-   double rebuildRatio,
-   size_t minRebuild):
-    R(R0),
-    _varCount(R->getNumVars()),
-        _minimizeOnInsert(minimizeOnInsert),
-        _moveDivisorToFront(moveDivisorToFront),
-  _sortOnInsert(sortOnInsert),
-  _useAutomaticRebuild((rebuildRatio > 0.0 || minRebuild > 0) && UDM),
-  _rebuildRatio(rebuildRatio),
-  _minRebuild(minRebuild),
-  _expQueryCount(0) {}
-
-  static const bool UseLinkedList = ULL;
-  static const bool UseDivMask = UDM;
-
-  const PolyRing *getPolyRing() const {return R;}
-  bool getDoAutomaticRebuilds() const {return _useAutomaticRebuild;}
-  double getRebuildRatio() const {return _rebuildRatio;}
-  size_t getRebuildMin() const {return _minRebuild;}
-  bool getSortOnInsert() const {return _sortOnInsert;}
-  bool getMinimizeOnInsert() const {return _minimizeOnInsert;}
-  bool getMoveDivisorToFront() const {return _moveDivisorToFront;}
-
-  size_t getVarCount() const {return _varCount;}
-
-  Exponent getExponent(const Monomial& m, size_t var) const {
-    ++_expQueryCount;
-    return R->monomialExponent(m, var);
-  }
-
-  bool divides(const Monomial& a, const Monomial& b) const {
-    for (size_t var = 0; var < getVarCount(); ++var)
-      if (getExponent(b, var) < getExponent(a, var))
-        return false;
-    return true;
-  }
-
-  bool isLessThan(const Monomial& a, const Monomial& b) const {
-    for (size_t var = 0; var < getVarCount(); ++var) {
-      if (getExponent(a, var) < getExponent(b, var))
-        return true;
-      if (getExponent(b, var) < getExponent(a, var))
-        return false;
-    }
-    return false;
-  }
-
-  unsigned long long getExpQueryCount() const {return _expQueryCount;}
-
- private:
-  const PolyRing *R;
-  const size_t _varCount;
-  const bool _minimizeOnInsert;
-  const bool _moveDivisorToFront;
-  const bool _sortOnInsert;
-  const bool _useAutomaticRebuild;
-  const double _rebuildRatio;
-  const size_t _minRebuild;
-  mutable unsigned long long _expQueryCount;
-};
-
-template<bool UseLinkedList, bool UseDivMask>
-class MonTableDivList;
-
-/** An instantiation of the capabilities of DivList. */
-template<bool ULL, bool UDM>
-class MonTableDivList {
- private:
-  typedef MonTableDivListConfiguration<ULL, UDM> C;
-  typedef mic::DivList<C> Finder;
- public:
-  typedef typename Finder::iterator iterator;
-  typedef typename Finder::const_iterator const_iterator;
-  typedef typename Finder::Monomial Monomial;
-  typedef typename Finder::Entry Entry;
-  typedef C Configuration;
-
-  MonTableDivList(const PolyRing *R,
-                          bool minimizeOnInsert,
-                          bool moveDivisorToFront,
-                          bool sortOnInsert,
-              double rebuildRatio,
-              size_t minRebuild):
-        _finder(C(R, minimizeOnInsert, moveDivisorToFront, sortOnInsert, rebuildRatio, minRebuild))
-  {
-    MATHICGB_ASSERT(!sortOnInsert || !moveDivisorToFront);
-  }
-
-  MonTableDivList(const Configuration &C) :
-        _finder(C)
-  {
-    MATHICGB_ASSERT(!C.getSortOnInsert() || !C.getMoveDivisorToFront());
-  }
-
-  const C& getConfiguration() const {return _finder.getConfiguration();}
-  C& getConfiguration() {return _finder.getConfiguration();}
-
-  bool getMinimizeOnInsert() const {return getConfiguration().getMinimizeOnInsert();}
-  bool getMoveDivisorToFront() const {return getConfiguration().getMoveDivisorToFront();}
-
-  bool insert(const Entry& entry);
-  template<class MultipleOutput>
-  bool insert(const Entry& entry, MultipleOutput& removed);
-
-  Entry* findDivisor(const Monomial& monomial) {
-    return _finder.findDivisor(monomial);
-  }
-
-  const Entry* findDivisor(const Monomial& monomial) const {
-    return const_cast<MonTableDivList<ULL, UDM>&>(*this).findDivisor(monomial);
-  }
-
-  template<class DO>
-  void findAllDivisors(const Monomial& monomial, DO& out) {
-    _finder.findAllDivisors(monomial, out);
-  }
-  template<class DO>
-  void findAllDivisors(const Monomial& monomial, DO& out) const {
-    _finder.findAllDivisors(monomial, out);
-  }
-
-  std::string getName() const;
-
-
-  iterator begin() {return _finder.begin();}
-  const_iterator begin() const {return _finder.begin();}
-  iterator end() {return _finder.end();}
-  const_iterator end() const {return _finder.end();}
-  size_t size() const {return _finder.size();}
-
-  unsigned long long getExpQueryCount() const {
-    return _finder.getConfiguration().getExpQueryCount();
-  }
-
-  void getMonomials(std::vector<const_monomial>& monomials);
-
-public:
-  typedef size_t ValueType;
-
-  const PolyRing * getPolyRing() const { return getConfiguration().getPolyRing(); }
-
-  bool member(const_monomial t) const {
-      const Entry* i = findDivisor(t);
-      if (i == 0) return false;
-      return true;
-  }
-  bool insert(const_monomial t, ValueType /* val */) { return insert(t); } // Only insert if not there
-
-  void display(std::ostream &o) const;
-
-  void dump(int level) const;
-
-  size_t n_elems() const { return size(); }
-
-  size_t getMemoryUse() const;
-
-  void displayStats(std::ostream &o) const;
-
-  struct Stats {
-    size_t n_member;
-    size_t n_inserts;  // includes koszuls
-    size_t n_insert_already_there;
-    size_t n_compares;
-  };
-
-  void getStats(Stats &stats) const { stats = stats_; }
-
- private:
-  Finder _finder;
-  Stats stats_;
-};
-
-template<bool ULL, bool UDM>
-inline bool MonTableDivList<ULL, UDM>::insert(const Entry& entry) {
-  if (!getMinimizeOnInsert()) {
-    _finder.insert(entry);
-    return true;
-  }
-  if (findDivisor(entry) != 0)
-    return false;
-  bool hasMultiples = _finder.removeMultiples(entry);
-  _finder.insert(entry);
-  if (getMoveDivisorToFront() && hasMultiples) {
-    iterator it = _finder.end();
-    _finder.moveToFront(--it);
-  }
-  return true;
-}
-
-template<bool ULL, bool UDM>
-template<class MO>
-inline bool MonTableDivList<ULL, UDM>::insert(const Entry& entry, MO& out) {
-  if (!getMinimizeOnInsert()) {
-    _finder.insert(entry);
-    return true;
-  }
-  if (findDivisor(entry) != _finder.end())
-    return false;
-  bool hasMultiples = _finder.removeMultiples(entry, out);
-  _finder.insert(entry);
-  if (getMoveDivisorToFront() && hasMultiples) {
-    iterator it = _finder.end();
-    _finder.moveToFront(--it);
-  }
-  return true;
-}
-
-template<bool ULL, bool UDM>
-inline std::string MonTableDivList<ULL, UDM>::getName() const {
-  return _finder.getName() +
-    (getMinimizeOnInsert() ? " remin" : " nomin") +
-    (getMoveDivisorToFront() ? " toFront" : "");
-}
-
-template <bool UDL, bool UDM>
-void MonTableDivList<UDL,UDM>::display(std::ostream &o) const
-{
-  const_iterator e = _finder.end();
-
-  for (const_iterator i=_finder.begin(); i != e; ++i)
-    {
-      getPolyRing()->monomialDisplay(o, *i, false);
-      o << "  ";
-    }
-  o << std::endl;
-}
-
-template <bool UDL, bool UDM>
-void MonTableDivList<UDL,UDM>::dump(int level) const
-{
-  displayStats(std::cerr);
-  if (level > 0) display(std::cerr);
-}
-
-template <bool UDL, bool UDM>
-size_t MonTableDivList<UDL,UDM>::getMemoryUse() const
-{
-  return _finder.getMemoryUse();
-}
-
-template <bool UDL, bool UDM>
-void MonTableDivList<UDL,UDM>::displayStats(std::ostream &o) const
-{
-  o << "  #elements: " << n_elems() <<  std::endl;
-  o << "  #calls member: " << stats_.n_member << std::endl;
-  o << "  #calls insert, but already there: " << stats_.n_insert_already_there << std::endl;
-  o << "  #compares: " << stats_.n_compares << std::endl;
-}
-
-template<bool UDL, bool UDM>
-void MonTableDivList<UDL, UDM>::getMonomials(std::vector<const_monomial>& monomials) {
-  monomials.insert(monomials.begin(), begin(), end());
-}
-
-MATHICGB_NAMESPACE_END
-#endif
diff --git a/src/mathicgb/MonTableKDTree.hpp b/src/mathicgb/MonTableKDTree.hpp
deleted file mode 100755
index f8b2889..0000000
--- a/src/mathicgb/MonTableKDTree.hpp
+++ /dev/null
@@ -1,290 +0,0 @@
-// 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_MON_TABLE_K_D_TREE_GUARD
-#define MATHICGB_MON_TABLE_K_D_TREE_GUARD
-
-#include "PolyRing.hpp"
-#include <string>
-#include <vector>
-#include <iostream>
-#include <memtailor.h>
-#include <mathic.h>
-
-MATHICGB_NAMESPACE_BEGIN
-
-/** Helper class for KDTreeModel. */
-template<bool UseDivMask, bool UseTreeDivMask, size_t LeafSize, bool AllowRemovals>
-class KDTreeModelConfiguration;
-
-template<bool UDM, bool UTDM, size_t LS, bool AR>
-class MonTableKDTreeConfiguration {
- public:
-  typedef int Exponent;
-  typedef const_monomial Monomial;
-  typedef Monomial Entry;
-
-  MonTableKDTreeConfiguration
-  (const PolyRing *R0,
-     bool minimizeOnInsert,
-     bool sortOnInsert,
-     bool useDivisorCache,
-     double rebuildRatio,
-     size_t minRebuild):
-        R(R0),
-        _varCount(R->getNumVars()),
-        _minimize_on_insert(minimizeOnInsert),
-   _sortOnInsert(sortOnInsert),
-   _useDivisorCache(useDivisorCache),
-   _useAutomaticRebuild((rebuildRatio > 0.0 || minRebuild > 0) && UDM),
-   _rebuildRatio(rebuildRatio),
-   _minRebuild(minRebuild),
-   _expQueryCount(0) {
-     MATHICGB_ASSERT(rebuildRatio >= 0);
-   }
-
-  size_t getVarCount() const {return _varCount;}
-  bool getSortOnInsert() const {return _sortOnInsert;}
-
-  Exponent getExponent(const Monomial& m, size_t var) const {
-    ++_expQueryCount;
-    return R->monomialExponent(m, var);
-  }
-
-  bool divides(const Monomial& a, const Monomial& b) const {
-    for (size_t var = 0; var < getVarCount(); ++var)
-      if (getExponent(b, var) < getExponent(a, var))
-        return false;
-    return true;
-  }
-
-  bool isLessThan(const Monomial& a, const Monomial& b) const {
-    for (size_t var = 0; var < getVarCount(); ++var) {
-      if (getExponent(a, var) < getExponent(b, var))
-        return true;
-      if (getExponent(b, var) < getExponent(a, var))
-        return false;
-        }
-    return false;
-  }
-
-  const PolyRing *getPolyRing() const {return R;}
-  bool getUseDivisorCache() const {return _useDivisorCache;}
-  bool getDoAutomaticRebuilds() const {return _useAutomaticRebuild;}
-  double getRebuildRatio() const {return _rebuildRatio;}
-  size_t getRebuildMin() const {return _minRebuild;}
-  bool getMinimizeOnInsert() const {return _minimize_on_insert;}
-  static const bool UseDivMask = UDM;
-  static const bool UseTreeDivMask = UTDM;
-  static const size_t LeafSize = LS;
-  static const bool PackedTree = true;
-  static const bool AllowRemovals = AR;
-
-  unsigned long long getExpQueryCount() const {return _expQueryCount;}
-
- private:
-  const PolyRing *R;
-  const size_t _varCount;
-  const bool _minimize_on_insert;
-  const bool _sortOnInsert;
-  const bool _useDivisorCache;
-  const bool _useAutomaticRebuild;
-  const double _rebuildRatio;
-  const size_t _minRebuild;
-  mutable unsigned long long _expQueryCount;
-};
-
-/** An instantiation of the capabilities of KDTree. */
-template<bool UseDivMask, bool UseTreeDivMask, size_t LeafSize, bool AllowRemovals>
-class MonTableKDTree {
- private:
-  typedef MonTableKDTreeConfiguration<UseDivMask, UseTreeDivMask, LeafSize, AllowRemovals> C;
-  typedef mic::KDTree<C> Finder;
- public:
-  typedef typename Finder::Monomial Monomial;
-  typedef typename Finder::Entry Entry;
-  typedef C Configuration;
-
-  MonTableKDTree(const PolyRing *R,
-                 bool minimizeOnInsert,
-                 bool sortOnInsert,
-                 bool useDivisorCache,
-                 double rebuildRatio,
-                 size_t minRebuild):
-        _finder(C(R, minimizeOnInsert, sortOnInsert, useDivisorCache, rebuildRatio, minRebuild))
-  {
-    MATHICGB_ASSERT(!UseTreeDivMask || UseDivMask);
-  }
-
-  MonTableKDTree(const Configuration &C) :
-        _finder(C)
-  {
-    MATHICGB_ASSERT(!UseTreeDivMask || UseDivMask);
-  }
-
-  const C& getConfiguration() const {return _finder.getConfiguration();}
-  C& getConfiguration() {return _finder.getConfiguration();}
-
-  bool insert(const Entry& entry);
-  template<class MultipleOutput>
-  bool insert(const Entry& entry, MultipleOutput& removed);
-
-  inline Entry* findDivisor(const Monomial& monomial) {
-    return _finder.findDivisor(monomial);
-  }
-  inline const Entry* findDivisor(const Monomial& monomial) const {
-    return _finder.findDivisor(monomial);
-  }
-  std::string getName() const;
-
-  template<class DO>
-  inline void findAllDivisors(const Monomial& monomial, DO& out) {
-    _finder.findAllDivisors(monomial, out);
-  }
-  template<class DO>
-  inline void findAllDivisors(const Monomial& monomial, DO& out) const {
-    _finder.findAllDivisors(monomial, out);
-  }
-
-  unsigned long long getExpQueryCount() const {
-    return _finder.getConfiguration().getExpQueryCount();
-  }
-
-  void getMonomials(std::vector<const_monomial>& monomials);
-
-public:
-  typedef size_t ValueType;
-
-  const PolyRing * getPolyRing() const { return getConfiguration().getPolyRing(); }
-
-  inline bool member(const_monomial t) const {
-    const Entry* entry = findDivisor(t);
-    if (entry == 0)
-      return false;
-    return true;
-  }
-  bool insert(const_monomial t, ValueType /* val */) { return insert(t); } // Only insert if not there
-
-  size_t n_elems() const { return _finder.size(); }
-
-  size_t getMemoryUse() const;
-
-  void displayStats(std::ostream &o) const;
-
-  struct Stats {
-    size_t n_member;
-    size_t n_inserts;  // includes koszuls
-    size_t n_insert_already_there;
-    size_t n_compares;
-  };
-
-  void getStats(Stats &stats) const { stats = stats_; }
-
- private:
-  Finder _finder;
-  Stats stats_;
-};
-
-class MonomialDeleter {
-public:
-  MonomialDeleter(const PolyRing& ring): mRing(ring) {}
-  void push_back(const void* p) {
-    mRing.freeMonomial(static_cast<exponent*>(const_cast<void*>(p)));
-  }
-  void push_back(ConstMonomial p) {
-    mRing.freeMonomial(const_cast<exponent *>(p.unsafeGetRepresentation()));
-  }
-private:
-  const PolyRing& mRing;
-};
-
-template<bool UDM, bool UTDM, size_t LS, bool AR>
-inline bool MonTableKDTree<UDM, UTDM, LS, AR>::insert(const Entry& entry) {
-  if (!getConfiguration().getMinimizeOnInsert()) {
-    _finder.insert(entry);
-    return true;
-  }
-  if (C::AllowRemovals) {
-    if (findDivisor(entry) != 0)
-      return false;
-    MonomialDeleter mondelete(*getPolyRing());
-    _finder.removeMultiples(entry, mondelete);
-  } else {
-    MATHICGB_ASSERT(findDivisor(entry) == 0);
-    MonomialDeleter mondelete(*getPolyRing());
-    // todo: can't do the below ASSERT as KD tree won't allow a
-    // removal action when removals are not allowed. So there
-    // should be a getMultiples() method that could be
-    // used instead.
-    //MATHICGB_ASSERT(!_finder.removeMultiples(entry, mondelete));
-  }
-  _finder.insert(entry);
-  return true;
-}
-
-template<bool UDM, bool UTDM, size_t LS, bool AR>
-template<class MultipleOutput>
-inline bool MonTableKDTree<UDM, UTDM, LS, AR>::
-insert(const Entry& entry, MultipleOutput& removed) {
-  if (!getConfiguration().getMinimizeOnInsert()) {
-    _finder.insert(entry);
-    return true;
-  }
-  if (C::AllowRemovals) {
-    if (findDivisor(entry) != _finder.end())
-      return false;
-    _finder.removeMultiples(entry, removed);
-  } else {
-    MATHICGB_ASSERT(findDivisor(entry) == _finder.end());
-    // todo: can't do the below ASSERT as KD tree won't allow a
-    // removal action when removals are not allowed. So there
-    // should be a getMultiples() method that could be
-    // used instead.
-    //MATHICGB_ASSERT(!_finder.removeMultiples(entry, removed));
-  }
-  _finder.insert(entry);
-  return true;
-}
-
-template<bool UDM, bool UTDM, size_t LS, bool AR>
-inline std::string MonTableKDTree<UDM, UTDM, LS, AR>::getName() const {
-  return _finder.getName() +
-    (getConfiguration().getMinimizeOnInsert() ? " remin" : " nomin");
-}
-
-template<bool UDM, bool UTDM, size_t LS, bool AR>
-size_t MonTableKDTree<UDM, UTDM, LS, AR>::getMemoryUse() const
-{
-  return _finder.getMemoryUse();
-}
-
-template <bool UDM, bool UTM, size_t LS, bool AR>
-void MonTableKDTree<UDM,UTM,LS, AR>::displayStats(std::ostream &o) const
-{
-  o << "  #elements: " << n_elems() <<  std::endl;
-  o << "  #calls member: " << stats_.n_member << std::endl;
-  o << "  #calls insert, but already there: " << stats_.n_insert_already_there << std::endl;
-  o << "  #compares: " << stats_.n_compares << std::endl;
-}
-
-namespace {
-  class ForAllCopy {
-  public:
-    ForAllCopy(std::vector<const_monomial>& monomials):
-      mMonomials(monomials) {}
-    bool proceed(const_monomial m) {
-      mMonomials.push_back(m);
-      return true;
-    }
-  private:
-    std::vector<const_monomial>& mMonomials;
-  };
-}
-
-template<bool UDM, bool UTM, size_t LS, bool AR>
-void MonTableKDTree<UDM, UTM, LS, AR>::getMonomials(std::vector<const_monomial>& monomials) {
-  ForAllCopy copier(monomials);
-  _finder.forAll(copier);
-}
-
-MATHICGB_NAMESPACE_END
-#endif
diff --git a/src/mathicgb/MonoLookup.cpp b/src/mathicgb/MonoLookup.cpp
index 58f861d..6a3cf40 100755
--- a/src/mathicgb/MonoLookup.cpp
+++ b/src/mathicgb/MonoLookup.cpp
@@ -11,7 +11,7 @@ MATHICGB_NAMESPACE_BEGIN
 
 namespace {
   template<
-    template<class> class BaseLookupTemplate,
+    bool UseKDTree,
     bool AllowRemovals,
     bool UseDivMask
   >
@@ -102,7 +102,8 @@ namespace {
     }
 
     virtual size_t divisor(ConstMonoRef mono) const {
-      return mLookup.divisor(mono);
+      const auto entry = mLookup.divisor(mono);
+      return entry == 0 ? size_t(-1) : entry->data();
     }
 
     virtual void divisors(ConstMonoRef mono, EntryOutput& consumer) const {
@@ -120,66 +121,13 @@ namespace {
     virtual size_t size() const {return mLookup.size();}
 
   private:
-    StaticMonoLookup<BaseLookupTemplate, AllowRemovals, UseDivMask> mLookup;
+    StaticMonoLookup<UseKDTree, size_t, AllowRemovals, UseDivMask> mLookup;
     const int mType;
     const bool mPreferSparseReducers;
     PolyBasis const* mBasis;
     SigPolyBasis const* mSigBasis;
   };
 
-  template<
-    template<class> class BaseLookup,
-    bool AllowRemovals,
-    bool UseDivMask
-  >
-  std::unique_ptr<MonoLookup> create(
-    const MonoLookup::Monoid& monoid,
-    int type,
-    bool preferSparseReducers
-  ) {
-    auto p = new ConcreteMonoLookup<BaseLookup, AllowRemovals, UseDivMask>
-      (monoid, type, preferSparseReducers);
-    return std::unique_ptr<MonoLookup>(p);
-  }
-
-  std::unique_ptr<MonoLookup> createGeneral(
-    const MonoLookup::Monoid& monoid,
-    int type,
-    bool preferSparseReducers,
-    bool allowRemovals
-  ) {
-    const bool sparse = preferSparseReducers;
-    switch (type) {
-    case 1:
-      if (allowRemovals)
-        return create<mathic::DivList, true, true>(monoid, type, sparse);
-      else
-        return create<mathic::DivList, false, true>(monoid, type, sparse);
-
-    case 2:
-      if (allowRemovals)
-        return create<mathic::KDTree, true, true>(monoid, type, sparse);
-      else
-        return create<mathic::KDTree, false, true>(monoid, type, sparse);
-
-    case 3:
-      if (allowRemovals)
-        return create<mathic::DivList, true, false>(monoid, type, sparse);
-      else
-        return create<mathic::DivList, false, false>(monoid, type, sparse);
-
-    case 4:
-      if (allowRemovals)
-        return create<mathic::KDTree, true, false>(monoid, type, sparse);
-      else
-        return create<mathic::KDTree, false, false>(monoid, type, sparse);
-
-    default:
-      MATHICGB_ASSERT_NO_ASSUME(false);
-      throw std::runtime_error("Unknown code for monomial data structure");
-    }
-  }
-
   class ConcreteFactory : public MonoLookup::Factory {
   public:
     ConcreteFactory(const Monoid& monoid, int type): 
@@ -191,11 +139,27 @@ namespace {
       bool preferSparseReducers,
       bool allowRemovals
     ) const {
-      return createGeneral
-        (mMonoid, mType, preferSparseReducers, allowRemovals);
+      Params params = {mMonoid, mType, preferSparseReducers};
+      return staticMonoLookupCreate
+        <Create, std::unique_ptr<MonoLookup>>(mType, allowRemovals, params);
     }
 
   private:
+    struct Params {
+      const Monoid& monoid;
+      int type;
+      bool preferSparseReducers;
+    };
+
+    template<bool UseKDTree, bool AllowRemovals, bool UseDivMask>
+    struct Create {
+      static std::unique_ptr<MonoLookup> create(const Params& params) {
+        auto p = new ConcreteMonoLookup<UseKDTree, AllowRemovals, UseDivMask>
+          (params.monoid, params.type, params.preferSparseReducers);
+        return std::unique_ptr<MonoLookup>(p);
+      }
+    };
+
     const Monoid& mMonoid;
     const int mType;
   };
diff --git a/src/mathicgb/MonoLookup.hpp b/src/mathicgb/MonoLookup.hpp
index 594e96d..09f0866 100755
--- a/src/mathicgb/MonoLookup.hpp
+++ b/src/mathicgb/MonoLookup.hpp
@@ -66,7 +66,6 @@ public:
   };
   static std::unique_ptr<Factory> makeFactory
     (const PolyRing& ring, int type);
-  // choices for type: 1: divlist, 2:kdtree.
 
   class EntryOutput {
   public:
diff --git a/src/mathicgb/StaticMonoLookup.hpp b/src/mathicgb/StaticMonoLookup.hpp
index 9f6ee6f..59ba6c2 100755
--- a/src/mathicgb/StaticMonoLookup.hpp
+++ b/src/mathicgb/StaticMonoLookup.hpp
@@ -17,8 +17,11 @@ MATHICGB_NAMESPACE_BEGIN
 /// Data structure for performing queries on a set of monomials.
 /// This is static in the sense that the interface is not virtual.
 template<
-  /// Should be mathic::DivList or mathic::KDTree
-  template<class> class BaseLookupTemplate,
+  /// Will use mathic::DivList or mathic::KDTree depending on this value.
+  bool UseKDTree,
+
+  /// Thing to store along with each monomial in the data structure.
+  class Data,
 
   /// Indicate whether elements should be allowed to be removed from the
   /// data structure. There can be a slight performance benefit from
@@ -31,7 +34,7 @@ template<
 >
 class StaticMonoLookup;
 
-template<template<class> class BaseLookupTemplate, bool AR, bool DM>
+template<bool UseKDTree, class Data, bool AR, bool DM>
 class StaticMonoLookup {
 private:
   typedef PolyRing::Monoid Monoid;
@@ -47,13 +50,24 @@ private:
 
     typedef int Exponent;
     typedef ConstMonoRef Monomial;
-    struct Entry {
-      Entry(): monom(), index(static_cast<size_t>(-1)) {}
-      Entry(ConstMonoRef monom0, size_t index0):
-        monom(monom0.ptr()), index(index0) {}
 
-      ConstMonoPtr monom;
-      size_t index;
+    class Entry {
+    public:
+      Entry(): mEntry() {}
+
+      template<class D>
+      Entry(ConstMonoRef mono, D&& data):
+        mEntry(mono.ptr(), std::forward<D>(data)) {}
+
+      ConstMonoRef mono() const {return *mEntry.first;}
+      const Data& data() const {return mEntry.second;}
+      Data& data() {return mEntry.second;}
+
+    private:
+      // Store in a std::pair so that if Data has no members then no space
+      // will be used on it. Here we are depending on std::pair to be using
+      // the empty base class optimization.
+      std::pair<ConstMonoPtr, Data> mEntry;
     };
 
     Exponent getExponent(const Monomial& m, size_t var) const {
@@ -61,7 +75,7 @@ private:
     }
 
     Exponent getExponent(const Entry& e, size_t var) const {
-      return monoid().exponent(*e.monom, var);
+      return monoid().exponent(e.mono(), var);
     }
 
     bool divides(const Monomial& a, const Monomial& b) const {
@@ -69,15 +83,15 @@ private:
     }
 
     bool divides(const Entry& a, const Monomial& b) const {
-      return monoid().divides(*a.monom, b);
+      return monoid().divides(a.mono(), b);
     }
 
     bool divides(const Monomial& a, const Entry& b) const {
-      return monoid().divides(a, *b.monom);
+      return monoid().divides(a, b.mono());
     }
 
     bool divides(const Entry& a, const Entry& b) const {
-      return monoid().divides(*a.monom, *b.monom);
+      return monoid().divides(a.mono(), b.mono());
     }
 
     bool getSortOnInsert() const {return false;}
@@ -108,7 +122,11 @@ private:
   };
 
 public:
-  typedef BaseLookupTemplate<Configuration> BaseLookup;
+  typedef typename std::conditional<
+    UseKDTree,
+    mathic::KDTree<Configuration>,
+    mathic::DivList<Configuration>
+  >::type BaseLookup;
   typedef typename BaseLookup::Entry Entry;
 
   static_assert
@@ -132,6 +150,16 @@ public:
     return LambdaWrap<Lambda>(lambda);
   }
 
+  template<class Lambda>
+  void forAll(Lambda&& lambda) const {
+    const auto wrap = [&](const Entry& entry){
+      lambda(entry);
+      return true;
+    };
+    auto outerWrap = lambdaWrap(wrap);
+    mLookup.forAll(outerWrap);
+  }
+
   // *** Signature specific functionality
 
   size_t regularReducer(
@@ -146,24 +174,24 @@ public:
 
     auto reducer = size_t(-1);
     auto proceed = [&, this](const Entry& e) {
-      if (ratioCmp.compare(e.index) != GT)
+      if (ratioCmp.compare(e.data()) != GT)
         return true;
 
       if (reducer != size_t(-1)) {
         if (preferSparseReducers) {
-          const auto newTermCount = basis.poly(e.index).nTerms();
+          const auto newTermCount = basis.poly(e.data()).nTerms();
           const auto oldTermCount = basis.poly(reducer).nTerms();
           if (newTermCount > oldTermCount)
             return true; // what we already have is sparser
           // resolve ties by picking oldest
-          if (newTermCount == oldTermCount && e.index > reducer)
+          if (newTermCount == oldTermCount && e.data() > reducer)
             return true;
         } else { // pick oldest
-          if (e.index > reducer)
+          if (e.data() > reducer)
             return true; // what we already have is older
         }
       }
-      reducer = e.index;
+      reducer = e.data();
       return true;
     };
     auto wrap = lambdaWrap(proceed);
@@ -179,18 +207,18 @@ public:
   ) const {
     MATHICGB_ASSERT(newGenerator < basis.size());
     auto proceed = [&](const Entry& entry) {
-      if (entry.index >= newGenerator)
+      if (entry.data() >= newGenerator)
         return true;
       for (size_t j = 0; j <= divisors.size(); ++j) {
         if (j == divisors.size()) {
-          divisors.push_back(entry.index);
+          divisors.push_back(entry.data());
           break;
         }
-        int cmp = basis.ratioCompare(entry.index, divisors[j]);
-        if (cmp == EQ && (entry.index < divisors[j]))
+        int cmp = basis.ratioCompare(entry.data(), divisors[j]);
+        if (cmp == EQ && (entry.data() < divisors[j]))
           cmp = GT; // prefer minimum index to ensure deterministic behavior
         if (cmp == GT) {
-          divisors.insert(divisors.begin() + j, entry.index);
+          divisors.insert(divisors.begin() + j, entry.data());
           break;
         }
       }
@@ -212,16 +240,16 @@ public:
     MATHICGB_ASSERT(newGenerator < basis.size());
     auto highDivisor = size_t(-1);
     auto proceed = [&](const Entry& entry) {
-      if (entry.index >= newGenerator)
+      if (entry.data() >= newGenerator)
         return true;
       if (highDivisor != size_t(-1)) {
-        int cmp = basis.ratioCompare(highDivisor, entry.index);
+        int cmp = basis.ratioCompare(highDivisor, entry.data());
         if (cmp == LT)
           return true;
-        if (cmp == EQ && (entry.index > highDivisor))
+        if (cmp == EQ && (entry.data() > highDivisor))
           return true; // prefer minimum index to ensure deterministic behavior
       }
-      highDivisor = entry.index;
+      highDivisor = entry.data();
       return true;
     };
     auto wrap = lambdaWrap(proceed);
@@ -247,14 +275,14 @@ public:
     auto minLeadGen = size_t(-1);
     auto proceed = [&](const Entry& entry) {
       if (minLeadGen != size_t(-1)) {
-        const int ratioCmp = basis.ratioCompare(entry.index, minLeadGen);
+        const int ratioCmp = basis.ratioCompare(entry.data(), minLeadGen);
         if (ratioCmp == LT)
           return true;
         if (ratioCmp == EQ) {
           // If same lead monomial in signature, pick the one with fewer terms
           // as that one might be less effort to reduce.
           const size_t minTerms = basis.poly(minLeadGen).nTerms();
-          const size_t terms = basis.poly(entry.index).nTerms();
+          const size_t terms = basis.poly(entry.data()).nTerms();
           if (minTerms > terms)
             return true;
           if (minTerms == terms) {
@@ -264,14 +292,14 @@ public:
             // is less. Also, as no two generators have same signature, this
             // ensures deterministic behavior.
             const auto minSig = basis.getSignature(minLeadGen);
-            const auto genSig = basis.getSignature(entry.index);
+            const auto genSig = basis.getSignature(entry.data());
             const auto sigCmp = basis.monoid().compare(minSig, genSig);
             if (basis.monoid().lessThan(genSig, minSig))
               return true;
           }
         }
       }
-      minLeadGen = entry.index;
+      minLeadGen = entry.data();
       return true;
     };
     auto wrap = lambdaWrap(proceed);
@@ -289,22 +317,22 @@ public:
     auto reducer = size_t(-1);
     auto proceed = [&](const Entry& entry) {
       if (reducer == size_t(-1)) {
-        reducer = entry.index;
+        reducer = entry.data();
         return true;
       }
       if (preferSparseReducers) {
         const auto oldTermCount = basis.poly(reducer).nTerms();
-        const auto newTermCount = basis.poly(entry.index).nTerms();
+        const auto newTermCount = basis.poly(entry.data()).nTerms();
         if (oldTermCount > newTermCount) {
-          reducer = entry.index; // prefer sparser
+          reducer = entry.data(); // prefer sparser
           return true;
         }
         if (oldTermCount < newTermCount)
           return true;
       } // break ties by age
 
-      if (reducer > entry.index)
-        reducer = entry.index; // prefer older
+      if (reducer > entry.data())
+        reducer = entry.data(); // prefer older
       return true;
     };
     auto wrap = lambdaWrap(proceed);
@@ -314,19 +342,18 @@ public:
 
   // *** General functionality
 
-  size_t divisor(ConstMonoRef mono) const {
-    const Entry* entry = mLookup.findDivisor(mono);
-    return entry == 0 ? static_cast<size_t>(-1) : entry->index;
+  const Entry* divisor(ConstMonoRef mono) const {
+    return mLookup.findDivisor(mono);
   }
 
   void divisors(ConstMonoRef mono, EntryOutput& consumer) const {
-    auto proceed = [&](const Entry& e) {return consumer.proceed(e.index);};
+    auto proceed = [&](const Entry& e) {return consumer.proceed(e.data());};
     auto wrap = lambdaWrap(proceed);
     mLookup.findAllDivisors(mono, wrap);
   }
 
   void multiples(ConstMonoRef mono, EntryOutput& consumer) const {
-    auto proceed = [&](const Entry& e) {return consumer.proceed(e.index);};
+    auto proceed = [&](const Entry& e) {return consumer.proceed(e.data());};
     auto wrap = lambdaWrap(proceed);
     mLookup.findAllMultiples(mono, wrap);
   }
@@ -344,13 +371,67 @@ public:
 
   size_t getMemoryUse() const {return mLookup.getMemoryUse();}
 
-  void insert(ConstMonoRef mono, size_t value) {
-    mLookup.insert(Entry(mono, value));
+  template<class D>
+  void insert(ConstMonoRef mono, D&& data) {
+    mLookup.insert(Entry(mono, std::forward<D>(data)));
   }
 
 private:
   BaseLookup mLookup;
 };
 
+/// Function for creating statically compiled classes that use
+/// StaticMonoLookup based on run-time values.
+///
+/// The type Functor must have an interface that is compatible with the
+/// following example.
+///
+/// template<bool UseKDTree, bool AllowRemovals, bool UseDivMask>
+/// struct Functor {
+///   static ReturnType create(const Params& params) {
+///     // do your thing
+///   }
+/// };
+template<
+  template<bool, bool, bool> class Functor,
+  class ReturnType,
+  class Params
+>
+ReturnType staticMonoLookupCreate(
+  int type,
+  bool allowRemovals,
+  Params&& params
+) {
+  switch (type) {
+  case 1:
+    if (allowRemovals)
+      return Functor<0, 1, 1>::create(std::forward<Params>(params));
+    else
+      return Functor<0, 0, 1>::create(std::forward<Params>(params));
+    
+  case 2:
+    if (allowRemovals)
+      return Functor<1, 1, 1>::create(std::forward<Params>(params));
+    else
+      return Functor<1, 0, 1>::create(std::forward<Params>(params));
+
+  case 3:
+    if (allowRemovals)
+      return Functor<0, 1, 0>::create(std::forward<Params>(params));
+    else
+      return Functor<0, 0, 0>::create(std::forward<Params>(params));
+
+  case 4:
+    if (allowRemovals)
+      return Functor<1, 1, 0>::create(std::forward<Params>(params));
+    else
+      return Functor<1, 0, 0>::create(std::forward<Params>(params));
+
+  default:
+    MATHICGB_ASSERT_NO_ASSUME(false);
+    throw std::runtime_error("Unknown code for monomial data structure");
+  }  
+}
+
 MATHICGB_NAMESPACE_END
 #endif
diff --git a/src/test/poly-test.cpp b/src/test/poly-test.cpp
index 2c43e7a..518e299 100755
--- a/src/test/poly-test.cpp
+++ b/src/test/poly-test.cpp
@@ -4,8 +4,6 @@
 #include "mathicgb/Poly.hpp"
 
 #include "mathicgb/Basis.hpp"
-#include "mathicgb/MonTableKDTree.hpp"
-#include "mathicgb/MonTableDivList.hpp"
 #include "mathicgb/MTArray.hpp"
 #include "mathicgb/io-util.hpp"
 #include "mathicgb/MonomialHashTable.hpp"

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