Macaulay2 Engine
Loading...
Searching...
No Matches
monomial-collection.hpp
Go to the documentation of this file.
1// Copyright 2018 Michael E. Stillman
2
3// TODO Feb 2018:
4// rename IntsSet (to e.g. ModuleMonomSet, making it not a template
5// sort() function: should match Matrix sort.
6// try to have a function return a ModuleMonomSet.
7// Monom, ModuleMonom:
8// try to remove operator[], etc, so the type is pretty much opaque.
9// add in another type: VarPowerMonom (or call it SparseMonom, SparseModuleMonom)
10// use these other types from M2FreeAlgebra, commutative version.
11// improve the hash function.
12// remove dead code, e.g. starting at #if 0 below.
13// use this code for coefficients, monomials, even in the commutative variant.
14// get M2FreeAlgebra.m2 so 'make check' works in a reasonable amount of time.
15// add in leadCoeff, leadMonomial, leadTerm. What other poly routines need to be added for M2FreeAlgebra?
16// consider looking at: https://github.com/skarupke/flat_hash_map
17// it is under boost license, it might be (not sure) well-written.
18
19#ifndef _monomial_collection_hpp_
20#define _monomial_collection_hpp_
21
59
60#include "Polynomial.hpp" // for ModuleMonom, monomToModuleMonom, Monom
61#include "style.hpp" // for EQ
62
63#include <memtailor/Arena.h> // for Arena
64#include <algorithm> // for sort
65#include <iomanip> // for operator<<, setw
66#include <iostream> // for operator<<, ostream, endl, cout, basic_...
67#include <iterator> // for bidirectional_iterator_tag, iterator_tr...
68#include <typeinfo> // for type_info
69#include <unordered_set> // for unordered_set
70#include <utility> // for pair
71#include <vector> // for vector
72
73template<typename T1, typename T2>
74std::ostream& operator << (std::ostream& o, const std::pair<T1,T2>& p)
75{
76 return o << "[" << p.first << "," << p.second << "]";
77}
78
79template<typename T>
80inline void PRINT_ELEMENTS(const T& collection, const std::string& prefix)
81{
82 std::cout << prefix;
83 for (const auto& elem : collection) {
84 std::cout << elem << ' ';
85 }
86 std::cout << std::endl;
87}
88
89template<typename T>
90void printHashTableState(const T& cont)
91{
92 // basic layout data
93 std::cout << "size: " << cont.size() << std::endl;
94 std::cout << "buckets: " << cont.bucket_count() << std::endl;
95 std::cout << "load factor: " << cont.load_factor() << std::endl;
96 std::cout << "max load factor: " << cont.max_load_factor() << std::endl;
97
98 // iterator category
99 if (typeid(typename std::iterator_traits<typename T::iterator>::iterator_category)
100 == typeid(std::bidirectional_iterator_tag))
101 {
102 std::cout << "chaining style: doubly-linked" << std::endl;
103 }
104 else
105 {
106 std::cout << "chaining style: singly-linked" << std::endl;
107 }
108
109 // elements per bucket
110 std::cout << "data: " << std::endl;
111 for (auto idx=0ul; idx != cont.bucket_count(); ++idx)
112 {
113 std::cout << " b[" << std::setw(2) << idx << "]: ";
114 for (auto pos = cont.begin(idx); pos != cont.end(idx); ++pos)
115 {
116 std::cout << *pos << " ";
117 }
118 std::cout << std::endl;
119 }
120}
121
122// Hash table for monomials (or ...)
123// Functions:
124// insert(monomial,comp): returns index if (monomial,comp) is in table. Otherwise sets value to next size.
125// lookup(monomial,comp): returns index.
126// A function elsewhere will loop through the monomials in a matrix, creating the hash table of these monomials.
127// actually: there might be translation from the monomials.
128// basically: (1) loop through monomials, add (transformed valued) one by one, when needed.
129// (2) loop through monomials, add monomial at row given by 'value' in hash table.
130// Structure itself:
131// hash table (probably from stl)
132// memtailor memory area for monomials.
133// number of elements contained in here
134// Memory management:
135// reserve space for a monomial (and/or copy it in).
136// jettison last one if not needed.
137
138// stores elements of type T*: points to a contiguous list of integers, first one is the length.
139// these are removed, when the hash table is removed. Hash value is also stored.
140
152{
153public:
154 bool operator()(const ModuleMonom& a, const ModuleMonom& b) const
155 {
156 auto cmp = ModuleMonom::compare(a,b);
157 return cmp <= EQ;
158 }
159};
160
169{
170public:
171 std::size_t operator()(const ModuleMonom& m) const
172 {
173 return m.hash();
174 }
175};
176
185{
186public:
187 bool operator() (const ModuleMonom& a, const ModuleMonom& b) const
188 {
189 return a == b;
190 }
191};
192
205{
206public:
208
211
212 std::size_t hash(const ModuleMonom& m) const
213 {
214 return m.hash();
215 }
216
217 bool keysEqual(const ModuleMonom& e1, const ModuleMonom& e2) const
218 {
219 if (e1[0] != e2[0]) return false;
220 for (int i=2; i < e1[0]; ++i)
221 if (e1[i] != e2[i]) return false;
222 return true;
223 }
224
225 std::size_t operator() (const ModuleMonom& e) const { return hash(e); }
226
227 bool operator() (const ModuleMonom& e1, const ModuleMonom& e2) const { return keysEqual(e1,e2); }
228
229 void display(std::ostream& o, const ModuleMonom& m) const
230 {
231 o << "val=" << m[1] << " [";
232 for (int i=3; i<3+m[0]; ++i)
233 o << m[i] << " ";
234 o << "comp=" << m[2] << std::endl;
235 }
236private:
238};
239
252{
253public:
256
257 ModuleMonomDefaultConfig(int nvars) : mNumVars(nvars) {}
259#if 0
260
261 std::size_t hash(const ModuleMonom& m) const
262 {
263 return m.hash();
264 }
265
266 bool keysEqual(const ModuleMonom& e1, const ModuleMonom& e2) const
267 {
268 if (e1[0] != e2[0]) return false;
269 for (int i=2; i < e1[0]; ++i)
270 if (e1[i] != e2[i]) return false;
271 return true;
272 }
273
274 std::size_t operator() (const ModuleMonom& e) const { return hash(e); }
275
276 bool operator() (const ModuleMonom& e1, const ModuleMonom& e2) const { return keysEqual(e1,e2); }
277
278 void display(std::ostream& o, const ModuleMonom& m) const
279 {
280 o << "val=" << m[1] << " [";
281 for (int i=3; i<3+m[0]; ++i)
282 o << m[i] << " ";
283 o << "comp=" << m[2] << std::endl;
284 }
285#endif
286private:
288};
289
290template<typename Configuration>
291// Configuration must include:
292// types: Monom, ModuleMonom
293// hash function: Configuration(ModuleMonom) --> std::size_t
294// equality check: Configuration(ModuleMonom, ModuleMonom) --> bool
295// copyToModuleElement: Configuration::copyToModuleElement(Monom, comp, val, ModuleMonom) --> void
296// value(ModuleMonom)
298{
299public:
300 using Conf = Configuration;
301 //using Set = std::unordered_set<ModuleMonom, Conf, Conf>;
302 using Set = std::unordered_set<ModuleMonom, ModuleMonomHash, ModuleMonomEq>;
303
304 IntsSet(Conf C) : mConf(C), mHash(100, C.Hash, C.Eq) {}
305
306 Configuration configuration() const { return mConf; }
307 const Set& set() const { return mHash; }
308 const std::vector<ModuleMonom>& uniqueMonoms() const { return mElements; }
309 std::size_t size() const { return mElements.size(); }
310
311 // insert (m,comp) into the set. Returns true if it is inserted, i.e. it isn't already in the set.
312 bool insert(Monom m, int comp)
313 {
315 std::pair<int*, int*> mon { mArena.allocArrayNoCon<int>(sz) };
316 ModuleMonom a = monomToModuleMonom(m, comp, mon);
317 auto result = mHash.insert(a);
318 bool new_elem = result.second;
319 if (new_elem)
320 {
321 a.setIndex(mElements.size());
322 mElements.push_back(a);
323 }
324 else
325 {
326 mArena.freeTop(a + 0);
327 }
328 return new_elem;
329 }
330
331 // if (m,comp) is found (and is a monomial with index idx), return {idx, true}
332 // if it is not found, return {-1, false}
333 std::pair<int,bool> find(Monom m, int comp)
334 {
336 std::pair<int*, int*> mon { mArena.allocArrayNoCon<int>(sz) };
337 ModuleMonom a = monomToModuleMonom(m, comp, mon);
338 auto result = mHash.find(a); // returns iterator pointing to value, or mHash.end()
339 bool found = (result != mHash.end());
340 int idx = (found ? result->index() : -1);
341 mArena.freeTop(mon.first);
342 return {idx, found};
343 }
344
345 // Resorts the monomials, changing their indices
346 void sort()
347 {
348 std::sort(mElements.begin(), mElements.end(), ModuleMonomLessThan());
349 for (int i=0; i<mElements.size(); ++i)
350 mElements[i].setIndex(i);
351 }
352
353 void display(std::ostream& o) const
354 {
355 // TODO: maybe we don't need this function.
356 for (auto& m : mElements)
357 o << " " << m << std::endl;
358 }
359
360 void stats(std::ostream& o) const
361 {
362 // TODO:
363 // display some info about hash table size, collisions.
364 // display memory usage (TODO: maybe memory usage should be a separate function too).
365 }
366
367 // hash table
368 // monomial arena
369 // list of pointers to these 'monomials' (so we can sort them?)
370 //
371 // data members:
372 // 1. arena
373 // 2. std::vector of int*'s into arena, unique monomials
374 // 3. unordered_set
375 // each monomial has a spot for its value. When inserted into the hash table, this value is set.
376 //
377 // Conf:
378 // hash function
379 // equality function
380 // comparison function on monomials (needs to be a different class, I think)
381 // Monomial ops:
382 // (monomial,comp) --> moduleMonomial (and back), put in space for int:
383 // --> [len, value, comp, v1, ..., vn] (len includes value)
384 // --> or [value, comp, len, deg, v1, ..., vr] (hash, length, equality, compare) all work on these.
385 //
386 // ops:
387 // H[mon,comp]: first copy monomial to arena, insert it. If there, pop monom, otherwise set 'value' field
388 // lookup: first copy monomial,comp to arena, lookup, then pop copied monomial.
389 // sortMonomials: sorts mons, sets 'value' field in each monomial.
390 // value(H[mon]) = 0-th int.
391private:
393 memt::Arena mArena; // memory area for monomials
394 Set mHash; // will need to put in hash function, compare fcn from Conf.
395 std::vector<ModuleMonom> mElements; // each monomial points into mArena.
396public:
397 auto begin() const -> decltype(mElements.begin()) { return mElements.begin(); }
398 auto end() const -> decltype(mElements.end()) { return mElements.end(); }
399};
400
402
403
404#endif
405
406// Local Variables:
407// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
408// indent-tabs-mode: nil
409// End:
ModuleMonom monomToModuleMonom(const Monom &a, int comp, std::pair< int *, int * > allocated_result)
Modern Monom / Polynomial value types shared by NC algebras and the refactored F4.
Word prefix(const Word vec, int lengthOfPrefix)
Configuration configuration() const
bool insert(Monom m, int comp)
void stats(std::ostream &o) const
std::unordered_set< ModuleMonom, ModuleMonomHash, ModuleMonomEq > Set
std::pair< int, bool > find(Monom m, int comp)
const Set & set() const
void display(std::ostream &o) const
auto begin() const -> decltype(mElements.begin())
auto end() const -> decltype(mElements.end())
std::size_t size() const
Configuration Conf
const std::vector< ModuleMonom > & uniqueMonoms() const
static int sizeOfCorrespondingModuleMonom(const Monom &m)
void setIndex(int idx)
std::size_t hash() const
static int compare(const ModuleMonom &m1, const ModuleMonom &m2)
ModuleMonomDefaultConfig(const ModuleMonomDefaultConfig &C)
std::size_t hash(const ModuleMonom &m) const
bool keysEqual(const ModuleMonom &e1, const ModuleMonom &e2) const
ModuleMonomDefaultConfigOrig(const ModuleMonomDefaultConfigOrig &C)
void display(std::ostream &o, const ModuleMonom &m) const
std::size_t operator()(const ModuleMonom &e) const
bool operator()(const ModuleMonom &a, const ModuleMonom &b) const
Equality functor on ModuleMonom, forwarding to operator==.
std::size_t operator()(const ModuleMonom &m) const
Hash functor on ModuleMonom, forwarding to ModuleMonom::hash.
Monom extended with a module component, a stored index, and a memoised hash — the value type of IntsS...
bool operator()(const ModuleMonom &a, const ModuleMonom &b) const
Strict-weak-order comparator on ModuleMonom, used by IntsSet::sort to reorder the insertion-ordered m...
int p
VALGRIND_MAKE_MEM_DEFINED & result(result)
IntsSet< ModuleMonomDefaultConfig > ModuleMonomialSet
std::ostream & operator<<(std::ostream &o, const std::pair< T1, T2 > &p)
void printHashTableState(const T &cont)
void PRINT_ELEMENTS(const T &collection, const std::string &prefix)
Non-owning view onto a [length, degree, v1, v2, ..., vn] packed monomial in some externally managed b...
int size
Definition table.c:30
const int EQ
Definition style.hpp:40
Engine-wide stylistic constants: LT / EQ / GT codes, INTSIZE, GEOHEAP_SIZE.
#define T
Definition table.c:13