13#include <mathic/Geobucket.h>
14#include <mathic/Heap.h>
15#include <mathic/TourTree.h>
25Reasoning about
using these structures in noncomm reduction.
28 Questions: how is the
monomial represented?
29 where is the allocated space
for it?
30 are they uniquely represented i.e. are we
using deduplicate, hashtable, etc?
33 Entry = pointer to [ringelem,
monomial pointer]
34 deduplicate: write this.
35 cmpLessThan:
monomial comparison call.
39 Pointer value could contain space
for the ringelem.
40 Entry = pointer to [ringelem,
monomial pointer]
422. Entry = PolyWithPosition
43 QueueConfiguration could own these polynomials (i.e. the Queue itself could).
44 we might need to write the
'value' function: keep popping off lead term, append to a poly.
46 monomial pool: use memtailor to generate
this space.
48 PolynomialWithPosition pool. [leadmonomial, coeff, lmon, rmon, index into the poly we are
using, which poly]
90 static const mathic::GeobucketBucketStorage
bucketStorage = mathic::GeoStoreSameSizeBuffer;
133 static const mathic::GeobucketBucketStorage
bucketStorage = mathic::GeoStoreSameSizeBuffer;
136std::unique_ptr<mathic::Geobucket<OurQueueConfiguration>>
makeQueue()
140 return std::make_unique<mathic::Geobucket<OurQueueConfiguration>>(C);
143std::unique_ptr<mathic::Geobucket<OurQueueConfiguration1>>
makeQueue1()
147 return std::make_unique<mathic::Geobucket<OurQueueConfiguration1>>(C);
193 const Poly& poly)
override
198 mRing.mult_by_term_left_and_right(
f, poly, coeff, left, right);
212 return std::make_pair(
mIter.monom(),
mIter.coeff());
233 std::string
getName()
const override {
return std::string(
"Trivial Heap"); }
263 using Entry = std::pair<Monom, ring_elem>;
268 int cmp =
mRing.monoid().compare(a.first, b.first);
273 std::cout <<
"Unexpected monomial comparison error in heap." << std::endl << std::flush;
299 static const mathic::GeobucketBucketStorage
bucketStorage = mathic::GeoStoreSameSizeBuffer;
319 using Entry = std::pair<Monom, ring_elem>;
324 int cmp =
mRing.monoid().compare(a.first, b.first);
329 std::cout <<
"Unexpected monomial comparison error in heap." << std::endl << std::flush;
350 return Entry(a.first, c);
358 static const mathic::GeobucketBucketStorage
bucketStorage = mathic::GeoStoreSameSizeBuffer;
363template<
template<
typename>
class Queue>
401 for (
auto i = poly.cbegin(); i != poly.cend(); ++i)
404 std::copy(i.monom().begin(), i.monom().end(), rg.first);
413 const Poly& poly)
override
416 mRing.mult_by_term_left_and_right(f, poly, coeff, left, right);
424 if (
mQueue.empty())
return true;
426 while (not
mQueue.empty())
430 if (
mRing.monoid().compare(e.first, lt.first) ==
EQ)
432 lt.second =
mRing.coefficientRing()->add(lt.second, e.second);
437 if (not
mRing.coefficientRing()->is_zero(lt.second))
447 if (not
mRing.coefficientRing()->is_zero(lt.second))
460 std::cout <<
"viewLeadTerm called without checking if polynomial is zero" << std::endl;
484 mRing.add_to_end(*f, tm.second, tm.first);
507template<
template<
typename>
class Queue>
537 for (
auto i = poly.cbegin(); i != poly.cend(); ++i)
540 std::copy(i.monom().begin(), i.monom().end(), rg.first);
549 const Poly& poly)
override
552 mRing.mult_by_term_left_and_right(f, poly, coeff, left, right);
560 while (not
mQueue.empty())
563 if (
mRing.coefficientRing()->is_zero(e.second))
587 mRing.add_to_end(*f, tm.second, tm.first);
603 Queue<NaiveDedupQueueConfiguration>
mQueue;
623 using Entry = std::pair<Monom, ring_elem>;
661 std::copy(tm.first.begin(), tm.first.end(), rg.first);
662 mMap.insert({
Monom(rg.first), tm.second});
668 for (
auto i = poly.cbegin(); i != poly.cend(); ++i)
678 const Poly& poly)
override
681 mRing.mult_by_term_left_and_right(f, poly, coeff, left, right);
689 while (not
mMap.empty())
692 if (
mRing.coefficientRing()->is_zero(e.second))
702 return * (
mMap.begin());
716 mRing.add_to_end(*f, tm.second, tm.first);
728 std::string
getName()
const override {
return "map heap"; }
734 std::map<Monom, ring_elem, MonomEq, gc_allocator<ConstEntry>>
mMap;
739class HashedConfiguration
742 HashedConfiguration(
const FreeAlgebra& F) : mRing(F) {}
745 using Term = Entry *;
748 enum class CompareResult {
LT,
EQ,
GT, Error};
749 CompareResult
compare(
const Entry& a,
const Entry& b)
const
751 int cmp = mRing.monoid().compare(a->second, b->second);
752 if (cmp ==
LT)
return CompareResult::LT;
753 if (cmp ==
GT)
return CompareResult::GT;
754 if (cmp ==
EQ)
return CompareResult::EQ;
756 std::cout <<
"Unexpected monomial comparison error in heap." << std::endl << std::flush;
757 return CompareResult::Error;
760 bool cmpLessThan(CompareResult a)
const {
return a == CompareResult::LT; }
763 const size_t minBucketSize = 2;
764 const size_t geoBase = 4;
765 static const size_t insertFactor = 4;
768 static const bool fastIndex =
false;
773 static const bool supportDeduplication =
false;
774 bool cmpEqual(CompareResult a)
const;
775 Entry deduplicate(Entry a, Entry b)
const;
777 static const bool minBucketBinarySearch =
true;
778 static const bool trackFront =
true;
779 static const bool premerge =
false;
780 static const bool collectMax =
true;
782 static const mathic::GeobucketBucketStorage bucketStorage = mathic::GeoStoreSameSizeBuffer;
785 size_t operator()(
const Term& term)
const
789 bool operator()(Term& term1, Term& term2)
const
791 return compare(&term1, &term2) == CompareResult::EQ;
794 const FreeAlgebra& mRing;
797template<
template<
typename>
class Queue>
801 using Term = HashedConfiguration::Term;
802 using Entry = HashedConfiguration::Entry;
804 HashedPolynomialHeap(
const FreeAlgebra& F)
806 mConfig(HashedConfiguration(F)),
808 mHash(1024, mConfig, mConfig)
812 virtual ~HashedPolynomialHeap() {}
816 HashedPolynomialHeap operator=(
const HashedPolynomialHeap&) =
delete;
817 HashedPolynomialHeap(
const HashedPolynomialHeap&) =
delete;
819 HashedPolynomialHeap& addTerm(Term tm)
821 auto result = mHash.find(tm);
822 bool found = (
result != mHash.end());
825 const_cast<ring_elem&
>(
result->first) = mRing.coefficientRing()->add(tm.first,
result->first);
830 auto rg = mMonomialSpace.allocateArray<
int>(tm.second.size());
831 std::copy(tm.second.begin(), tm.second.end(), rg.first);
832 mQueue.push(&*(inserted.first));
833 auto inserted = mHash.insert(Term(tm.first, rg.first));
840 for (
auto i = poly.cbegin(); i != poly.cend(); ++i)
841 addTerm(Term(i.coeff(), i.monom()));
848 const Poly& poly)
override
851 mRing.mult_by_term_left_and_right(f, poly, coeff, left, right);
859 while (not mQueue.empty())
861 Entry e = mQueue.top();
862 if (mRing.coefficientRing()->is_zero(e->first))
872 return * mQueue.top();
889 mRing.add_to_end(*f, tm.first, tm.second);
898 return mQueue.getMemoryUse() + mMonomialSpace.getMemoryUsedInBytes();
901 std::string
getName()
const override {
return mQueue.getName(); }
905 HashedConfiguration mConfig;
906 Queue<HashedConfiguration> mQueue;
907 std::unordered_map<Monom, ring_elem, HashedConfiguration, HashedConfiguration> mHash;
908 MemoryBlock mMonomialSpace;
930 using Entry = std::pair<Monom,ring_elem>;
944 return mMonoid.compare(a.first, b.first) ==
LT;
969 using Entry = std::pair<Monom, ring_elem>;
970 using Container = std::vector<Entry, StatsAllocator<Entry>>;
1002 std::copy(entry.first.begin(), entry.first.end(), rg.first);
1014 for (
auto i = poly.cbegin(); i != poly.cend(); ++i)
1022 const Poly& poly)
override
1026 mRing.mult_by_term_left_and_right(f, poly, coeff, left, right);
1034 if (
mQueue.empty())
return true;
1037 while (not
mQueue.empty())
1040 if (
mRing.monoid().compare(e.first, lt.first) ==
EQ)
1042 lt.second =
mRing.coefficientRing()->add(lt.second, e.second);
1047 if (not
mRing.coefficientRing()->is_zero(lt.second))
1060 if (not
mRing.coefficientRing()->is_zero(lt.second))
1073 std::cout <<
"viewLeadTerm called without checking if polynomial is zero" << std::endl;
1097 mRing.add_to_end(*f, tm.second, tm.first);
1109 std::string
getName()
const override {
return "Priority queue heap."; }
1114 std::priority_queue<Entry,Container,EntryConfig>
mQueue;
1126 switch (strategy & 7) {
1144 return "PriorityQueue";
1148 return "NaiveDedupGeobucket";
1150 return "NaiveGeobucket";
1152 return "NaiveTourTree";
1155 default:
return "Map";
1161std::unique_ptr<PolynomialHeap>
1168 return std::make_unique<MapPolynomialHeap>(F);
1170 return std::make_unique<PriorityQueuePolynomialHeap>(F);
1172 return std::make_unique<TrivialPolynomialHeap>(F);
1174 return std::make_unique<NaiveDedupPolynomialHeap<mathic::Geobucket>>(F);
1176 return std::make_unique<NaivePolynomialHeap<mathic::Geobucket>>(F);
1178 return std::make_unique<NaivePolynomialHeap<mathic::TourTree>>(F);
1180 return std::make_unique<NaivePolynomialHeap<mathic::Heap>>(F);
1187 std::cout <<
"trying out mathic code!" << std::endl;
1195 while (not Q->empty())
1198 std::cout <<
"popped: " << a << std::endl;
1202 std::cout <<
"trying out mathic code, part 2!" << std::endl;
1210 while (not Q1->empty())
1213 std::cout <<
"popped: " << a << std::endl;
Free associative algebra k<x_1,...,x_n> over an arbitrary coefficient ring.
FreeMonoid — monoid of length-prefixed non-commutative words with weight-vector prefix.
Bump-pointer arena allocator for transient inner-loop allocations.
NCGroebner — Buchberger-style two-sided Gröbner basis driver over a FreeAlgebra.
std::unique_ptr< PolynomialHeap > makePolynomialHeap(HeapType type, const FreeAlgebra &F)
std::string getHeapName(HeapType type)
std::unique_ptr< mathic::Geobucket< OurQueueConfiguration > > makeQueue()
HeapType getHeapType(int strategy)
std::unique_ptr< mathic::Geobucket< OurQueueConfiguration1 > > makeQueue1()
PolynomialHeap abstract interface — batched-subtraction heap for non-commutative reduction.
Polynomial< CoefficientRingType > Poly
Word and WordWithData — non-owning views over the flat-int encoding of a non-commutative word.
const FreeMonoid & mMonoid
size_t operator()(Monom m) const
std::pair< Monom, ring_elem > Entry
EntryConfig(const FreeMonoid &M)
Comparator (and trivial hash) functor wired into the std::priority_queue inside PriorityQueuePolynomi...
Free associative algebra over a coefficient ring: the non-commutative analogue of PolynomialRing.
The free non-commutative monoid on a set of named variables, with monomial ordering and degree / weig...
MemoryBlock mMonomialSpace
MapPolynomialHeap operator=(const MapPolynomialHeap &)=delete
std::pair< Monom, ring_elem > Entry
std::string getName() const override
std::map< Monom, ring_elem, MonomEq, gc_allocator< ConstEntry > > mMap
virtual ~MapPolynomialHeap()
MapPolynomialHeap & addPolynomial(ring_elem coeff, Word left, Word right, const Poly &poly) override
void removeLeadTerm() override
size_t getMemoryUsedInBytes() override
Entry viewLeadTerm() override
MapPolynomialHeap & addPolynomial(const Poly &poly) override
std::pair< const Monom, ring_elem > ConstEntry
MapPolynomialHeap(const MapPolynomialHeap &)=delete
MapPolynomialHeap(const FreeAlgebra &F)
Thin RAII wrapper around memtailor::Arena providing bump-pointer array allocation with optional mutex...
Strict comparator on Monoms under a FreeMonoid order: returns true exactly when the first monomial is...
MemoryBlock mMonomialSpace
size_t getMemoryUsedInBytes() override
Queue< NaiveDedupQueueConfiguration > mQueue
void removeLeadTerm() override
NaiveDedupPolynomialHeap operator=(const NaiveDedupPolynomialHeap &)=delete
NaiveDedupPolynomialHeap(const FreeAlgebra &F)
std::string getName() const override
NaiveDedupPolynomialHeap & addPolynomial(const Poly &poly) override
NaiveDedupPolynomialHeap & addPolynomial(ring_elem coeff, Word left, Word right, const Poly &poly) override
NaiveDedupQueueConfiguration::Entry Entry
NaiveDedupPolynomialHeap(const NaiveDedupPolynomialHeap &)=delete
virtual ~NaiveDedupPolynomialHeap()
std::pair< Monom, ring_elem > viewLeadTerm() override
static const mathic::GeobucketBucketStorage bucketStorage
CompareResult compare(const Entry &a, const Entry &b) const
const size_t minBucketSize
bool cmpEqual(CompareResult a) const
static const bool fastIndex
static const bool minBucketBinarySearch
static const bool collectMax
static const bool trackFront
NaiveDedupQueueConfiguration(const FreeAlgebra &F)
bool cmpLessThan(CompareResult a) const
std::pair< Monom, ring_elem > Entry
const FreeAlgebra & mRing
static const bool premerge
Entry deduplicate(Entry a, Entry b) const
static const size_t insertFactor
static const bool supportDeduplication
Variant of NaiveQueueConfiguration with deduplication enabled: deduplicate(a, b) sums the coefficient...
NaivePolynomialHeap & addPolynomial(ring_elem coeff, Word left, Word right, const Poly &poly) override
NaiveQueueConfiguration::Entry Entry
virtual ~NaivePolynomialHeap()
Queue< NaiveQueueConfiguration > mQueue
std::pair< Monom, ring_elem > mLeadTerm
NaivePolynomialHeap & addPolynomial(const Poly &poly) override
MemoryBlock mMonomialSpace
NaivePolynomialHeap(const NaivePolynomialHeap &)=delete
size_t getMemoryUsedInBytes() override
std::pair< Monom, ring_elem > viewLeadTerm() override
void removeLeadTerm() override
std::string getName() const override
NaivePolynomialHeap(const FreeAlgebra &F)
NaivePolynomialHeap operator=(const NaivePolynomialHeap &)=delete
bool cmpEqual(CompareResult a) const
static const mathic::GeobucketBucketStorage bucketStorage
CompareResult compare(const Entry &a, const Entry &b) const
static const bool supportDeduplication
static const bool premerge
static const bool minBucketBinarySearch
Entry deduplicate(Entry a, Entry b) const
static const size_t insertFactor
const FreeAlgebra & mRing
static const bool trackFront
const size_t minBucketSize
static const bool fastIndex
bool cmpLessThan(CompareResult a) const
static const bool collectMax
NaiveQueueConfiguration(const FreeAlgebra &F)
std::pair< Monom, ring_elem > Entry
mathic::Geobucket configuration whose Entry is a (Monom, ring_elem) pair compared by the FreeMonoid o...
CompareResult compare(const Entry &a, const Entry &b) const
bool cmpEqual(CompareResult a) const
static const bool trackFront
static const bool collectMax
static const bool minBucketBinarySearch
Entry deduplicate(Entry a, Entry b) const
bool cmpLessThan(CompareResult a) const
static const bool supportDeduplication
static const mathic::GeobucketBucketStorage bucketStorage
const size_t minBucketSize
static const bool premerge
static const size_t insertFactor
Variant of OurQueueConfiguration with deduplication enabled, used by makeQueue1().
bool cmpLessThan(CompareResult a) const
static const bool premerge
const size_t minBucketSize
Entry deduplicate(Entry a, Entry b) const
static const size_t insertFactor
bool cmpEqual(CompareResult a) const
static const bool collectMax
static const bool supportDeduplication
static const mathic::GeobucketBucketStorage bucketStorage
CompareResult compare(const Entry &a, const Entry &b) const
static const bool minBucketBinarySearch
static const bool trackFront
Experimental mathic::Geobucket configuration whose Entry is an int — a placeholder used by makeQueue(...
virtual void removeLeadTerm()=0
virtual std::pair< Monom, ring_elem > viewLeadTerm()=0
virtual size_t getMemoryUsedInBytes()=0
virtual std::string getName() const =0
virtual PolynomialHeap & addPolynomial(const Poly &poly)=0
Abstract interface for accumulating a polynomial as a sum of (coeff, left * poly * right) contributio...
PriorityQueuePolynomialHeap & addPolynomial(ring_elem coeff, Word left, Word right, const Poly &poly) override
PriorityQueuePolynomialHeap & addPolynomial(const Poly &poly) override
std::pair< Monom, ring_elem > viewLeadTerm() override
std::priority_queue< Entry, Container, EntryConfig > mQueue
void removeLeadTerm() override
PriorityQueuePolynomialHeap operator=(const PriorityQueuePolynomialHeap &)=delete
size_t getMemoryUsedInBytes() override
PriorityQueuePolynomialHeap(const PriorityQueuePolynomialHeap &)=delete
PriorityQueuePolynomialHeap & addEntry(const Entry &entry)
std::string getName() const override
std::pair< Monom, ring_elem > Entry
std::vector< Entry, StatsAllocator< Entry > > Container
MemoryBlock mMonomialSpace
virtual ~PriorityQueuePolynomialHeap()
PriorityQueuePolynomialHeap(const FreeAlgebra &F)
Poly::const_iterator mIter
TrivialPolynomialHeap(const FreeAlgebra &F)
std::string getName() const override
TrivialPolynomialHeap operator=(const TrivialPolynomialHeap &)=delete
TrivialPolynomialHeap & addPolynomial(ring_elem coeff, Word left, Word right, const Poly &poly) override
TrivialPolynomialHeap(const TrivialPolynomialHeap &)=delete
void removeLeadTerm() override
size_t getMemoryUsedInBytes() override
virtual ~TrivialPolynomialHeap()
std::pair< Monom, ring_elem > viewLeadTerm() override
PolynomialHeap & addPolynomial(const Poly &poly) override
Non-owning view of a non-commutative word: [begin, end) of int variable indices.
std::list< brMonomial > monomials
static int compare(const vecterm *t, const vecterm *s)
VALGRIND_MAKE_MEM_DEFINED & result(result)
AllocLogger / StatsAllocator — single-threaded debug/benchmark instrumentation.
void swap(mpfr::mpreal &x, mpfr::mpreal &y)
Ring — the legacy abstract base class for every coefficient and polynomial ring.
Non-owning view onto a [length, degree, v1, v2, ..., vn] packed monomial in some externally managed b...
Engine-wide stylistic constants: LT / EQ / GT codes, INTSIZE, GEOHEAP_SIZE.