Actual source code: Sifter.hh
1: #ifndef included_ALE_Sifter_hh
2: #define included_ALE_Sifter_hh
4: #include <boost/multi_index_container.hpp>
5: #include <boost/multi_index/member.hpp>
6: #include <boost/multi_index/ordered_index.hpp>
7: #include <boost/multi_index/composite_key.hpp>
8: #include <iostream>
10: // ALE extensions
12: #ifndef included_ALE_hh
13: #include <ALE.hh>
14: #endif
16: namespace ALE {
18: namespace def {
19: //
20: // This is a set of classes and class templates describing an interface to point containers.
21: //
23: // Basic object
24: class Point {
25: public:
26: int32_t prefix, index;
27: // Constructors
28: Point() : prefix(0), index(0){};
29: Point(int p, int i) : prefix(p), index(i){};
30: Point(const Point& p) : prefix(p.prefix), index(p.index){};
31: // Comparisons
32: bool operator==(const Point& q) const {
33: return ( (this->prefix == q.prefix) && (this->index == q.index) );
34: };
35: bool operator!=(const Point& q) const {
36: return ( (this->prefix != q.prefix) || (this->index != q.index) );
37: };
38: bool operator<(const Point& q) const {
39: return( (this->prefix < q.prefix) || ((this->prefix == q.prefix) && (this->index < q.index)));
40: };
41: // Printing
42: friend std::ostream& operator<<(std::ostream& os, const Point& p) {
43: os << "(" << p.prefix << ", "<< p.index << ")";
44: return os;
45: };
46: };
47: typedef std::set<Point> PointSet;
48: typedef std::vector<Point> PointArray;
50: template <typename Source_, typename Target_, typename Color_>
51: struct Arrow {
52: Source_ source;
53: Target_ target;
54: Color_ color;
56: Arrow(Source_ s, Target_ t, Color_ c) : source(s), target(t), color(c) {};
57: friend std::ostream& operator<<(std::ostream& os, const Arrow& a) {
58: os << a.source << " --" << a.color << "--> " << a.target << std::endl;
59: return os;
60: }
61: };
63: //
64: // BiGraph (short for BipartiteGraph) implements a sequential interface similar to that of Sieve (below),
65: // except the source and target points may have different types and iterated operations (e.g., nCone, closure)
66: // are not available.
67: //
68: template<typename Source_, typename Target_, typename Color_>
69: class BiGraph {
70: public:
71: typedef Source_ source_type;
72: typedef Target_ target_type;
73: typedef Color_ color_type;
74: int debug;
75: private:
76: // Arrow storage
77: struct source{};
78: struct target{};
79: struct color{};
80: struct sourceColor{};
81: struct targetColor{};
82: typedef Arrow<source_type,target_type,color_type> Arrow_;
83: typedef ::boost::multi_index::multi_index_container<
84: Arrow_,
85: ::boost::multi_index::indexed_by<
86: ::boost::multi_index::ordered_non_unique<
87: ::boost::multi_index::tag<source>, BOOST_MULTI_INDEX_MEMBER(Arrow_,source_type,source)>,
88: ::boost::multi_index::ordered_non_unique<
89: ::boost::multi_index::tag<target>, BOOST_MULTI_INDEX_MEMBER(Arrow_,target_type,target)>,
90: ::boost::multi_index::ordered_non_unique<
91: ::boost::multi_index::tag<color>, BOOST_MULTI_INDEX_MEMBER(Arrow_,color_type,color)>,
92: ::boost::multi_index::ordered_non_unique<
93: ::boost::multi_index::tag<sourceColor>,
94: ::boost::multi_index::composite_key<
95: Arrow_, BOOST_MULTI_INDEX_MEMBER(Arrow_,source_type,source), BOOST_MULTI_INDEX_MEMBER(Arrow_,color_type,color)>
96: >,
97: ::boost::multi_index::ordered_non_unique<
98: ::boost::multi_index::tag<targetColor>,
99: ::boost::multi_index::composite_key<
100: Arrow_, BOOST_MULTI_INDEX_MEMBER(Arrow_,target_type,target), BOOST_MULTI_INDEX_MEMBER(Arrow_,color_type,color)>
101: >
102: >,
103: ALE_ALLOCATOR<Arrow_>
104: > ArrowSet;
105: ArrowSet arrows;
107: struct point{};
108: struct depthTag{};
109: struct heightTag{};
110: struct indegree{};
111: struct outdegree{};
112: struct StratumPoint {
113: target_type point;
114: int depth;
115: int height;
116: int indegree;
117: int outdegree;
119: StratumPoint() : depth(0), height(0), indegree(0), outdegree(0) {};
120: StratumPoint(const target_type& p) : point(p), depth(0), height(0), indegree(0), outdegree(0) {};
121: // Printing
122: friend std::ostream& operator<<(std::ostream& os, const StratumPoint& p) {
123: os << "[" << p.point << ", "<< p.depth << ", "<< p.height << ", "<< p.indegree << ", "<< p.outdegree << "]";
124: return os;
125: };
126: };
127: typedef ::boost::multi_index::multi_index_container<
128: StratumPoint,
129: ::boost::multi_index::indexed_by<
130: ::boost::multi_index::ordered_unique<
131: ::boost::multi_index::tag<point>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,target_type,point)>,
132: ::boost::multi_index::ordered_non_unique<
133: ::boost::multi_index::tag<depthTag>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,depth)>,
134: ::boost::multi_index::ordered_non_unique<
135: ::boost::multi_index::tag<heightTag>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,height)>,
136: ::boost::multi_index::ordered_non_unique<
137: ::boost::multi_index::tag<indegree>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,indegree)>,
138: ::boost::multi_index::ordered_non_unique<
139: ::boost::multi_index::tag<outdegree>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,outdegree)>
140: >,
141: ALE_ALLOCATOR<StratumPoint>
142: > StratumSet;
143: StratumSet strata;
144: bool stratification;
145: int maxDepth;
146: int maxHeight;
147: int graphDiameter;
148: public:
149: BiGraph() : debug(0), stratification(false), maxDepth(-1), maxHeight(-1), graphDiameter(-1) {};
150: // Return types
151: class baseSequence {
152: const typename ::boost::multi_index::index<StratumSet,indegree>::type& baseIndex;
153: public:
154: class iterator {
155: public:
156: typedef std::input_iterator_tag iterator_category;
157: typedef target_type value_type;
158: typedef int difference_type;
159: typedef target_type* pointer;
160: typedef target_type& reference;
161: typename boost::multi_index::index<StratumSet,indegree>::type::iterator pointIter;
163: iterator(const typename boost::multi_index::index<StratumSet,indegree>::type::iterator& iter) {
164: this->pointIter = typename boost::multi_index::index<StratumSet,indegree>::type::iterator(iter);
165: };
166: virtual ~iterator() {};
167: //
168: virtual iterator operator++() {++this->pointIter; return *this;};
169: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
170: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
171: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
172: virtual const target_type& operator*() const {return this->pointIter->point;};
173: };
175: baseSequence(const typename ::boost::multi_index::index<StratumSet,indegree>::type& base) : baseIndex(base) {};
176: virtual ~baseSequence() {};
177: virtual iterator begin() {return iterator(this->baseIndex.upper_bound(0));};
178: virtual iterator end() {return iterator(this->baseIndex.end());};
179: virtual std::size_t size() {return -1;};
180: };
181: class capSequence {
182: const typename ::boost::multi_index::index<StratumSet,outdegree>::type& capIndex;
183: public:
184: class iterator {
185: public:
186: typedef std::input_iterator_tag iterator_category;
187: typedef target_type value_type;
188: typedef int difference_type;
189: typedef target_type* pointer;
190: typedef target_type& reference;
191: typename boost::multi_index::index<StratumSet,outdegree>::type::iterator pointIter;
193: iterator(const typename boost::multi_index::index<StratumSet,outdegree>::type::iterator& iter) {
194: this->pointIter = typename boost::multi_index::index<StratumSet,outdegree>::type::iterator(iter);
195: };
196: virtual ~iterator() {};
197: //
198: virtual iterator operator++() {++this->pointIter; return *this;};
199: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
200: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
201: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
202: virtual const target_type& operator*() const {return this->pointIter->point;};
203: };
205: capSequence(const typename ::boost::multi_index::index<StratumSet,outdegree>::type& cap) : capIndex(cap) {};
206: virtual ~capSequence() {};
207: virtual iterator begin() {return iterator(this->capIndex.upper_bound(0));};
208: virtual iterator end() {return iterator(this->capIndex.end());};
209: virtual std::size_t size() {return -1;};
210: };
211: class coneSequence {
212: typename ::boost::multi_index::index<ArrowSet,targetColor>::type& coneIndex;
213: const target_type key;
214: const color_type color;
215: const bool useColor;
216: struct changeColor {
217: changeColor(color_type newColor) : newColor(newColor) {};
219: void operator()(Arrow_& p) {
220: p.color = newColor;
221: }
222: private:
223: color_type newColor;
224: };
225: public:
226: class iterator {
227: typename ::boost::multi_index::index<ArrowSet,targetColor>::type& index;
228: public:
229: typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator arrowIter;
231: iterator(typename ::boost::multi_index::index<ArrowSet,targetColor>::type& index, const typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator& iter) : index(index) {
232: this->arrowIter = typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator(iter);
233: };
234: virtual ~iterator() {};
235: //
236: virtual iterator operator++() {++this->arrowIter; return *this;};
237: virtual iterator operator++(int n) {iterator tmp(this->index, this->arrowIter); ++this->arrowIter; return tmp;};
238: virtual iterator operator--() {--this->arrowIter; return *this;};
239: virtual iterator operator--(int n) {iterator tmp(this->index, this->arrowIter); --this->arrowIter; return tmp;};
240: virtual bool operator==(const iterator& itor) const {return this->arrowIter == itor.arrowIter;};
241: virtual bool operator!=(const iterator& itor) const {return this->arrowIter != itor.arrowIter;};
242: virtual const source_type& operator*() const {return this->arrowIter->source;};
243: void setColor(int newColor) {this->index.modify(this->arrowIter, changeColor(newColor));};
244: };
245: class reverse_iterator {
246: public:
247: typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator arrowIter;
249: reverse_iterator(const typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator& iter) {
250: this->arrowIter = typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator(iter);
251: };
252: virtual ~reverse_iterator() {};
253: //
254: virtual reverse_iterator operator++() {--this->arrowIter; return *this;};
255: virtual reverse_iterator operator++(int n) {reverse_iterator tmp(this->arrowIter); --this->arrowIter; return tmp;};
256: virtual bool operator==(const reverse_iterator& itor) const {return this->arrowIter == itor.arrowIter;};
257: virtual bool operator!=(const reverse_iterator& itor) const {return this->arrowIter != itor.arrowIter;};
258: virtual const source_type& operator*() const {return this->arrowIter->source;};
259: };
261: coneSequence(typename ::boost::multi_index::index<ArrowSet,targetColor>::type& cone, const target_type& p) : coneIndex(cone), key(p), color(color_type()), useColor(0) {};
262: coneSequence(typename ::boost::multi_index::index<ArrowSet,targetColor>::type& cone, const target_type& p, const color_type& c) : coneIndex(cone), key(p), color(c), useColor(1) {};
263: virtual ~coneSequence() {};
264: virtual iterator begin() {
265: if (useColor) {
266: return iterator(this->coneIndex, this->coneIndex.lower_bound(::boost::make_tuple(key,color)));
267: } else {
268: return iterator(this->coneIndex, this->coneIndex.lower_bound(::boost::make_tuple(key)));
269: }
270: };
271: virtual iterator end() {
272: if (useColor) {
273: return iterator(this->coneIndex, this->coneIndex.upper_bound(::boost::make_tuple(key,color)));
274: } else {
275: return iterator(this->coneIndex, this->coneIndex.upper_bound(::boost::make_tuple(key)));
276: }
277: };
278: virtual reverse_iterator rbegin() {
279: if (useColor) {
280: return reverse_iterator(--this->coneIndex.upper_bound(::boost::make_tuple(key,color)));
281: } else {
282: return reverse_iterator(--this->coneIndex.upper_bound(::boost::make_tuple(key)));
283: }
284: };
285: virtual reverse_iterator rend() {
286: typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator i;
288: if (useColor) {
289: return reverse_iterator(--this->coneIndex.lower_bound(::boost::make_tuple(key,color)));
290: } else {
291: return reverse_iterator(--this->coneIndex.lower_bound(::boost::make_tuple(key)));
292: }
293: };
294: virtual std::size_t size() {
295: if (useColor) {
296: return this->coneIndex.count(::boost::make_tuple(key,color));
297: } else {
298: return this->coneIndex.count(::boost::make_tuple(key));
299: }
300: };
301: };
302: class supportSequence {
303: const typename ::boost::multi_index::index<ArrowSet,sourceColor>::type& supportIndex;
304: const source_type key;
305: const color_type color;
306: const bool useColor;
307: public:
308: class iterator {
309: public:
310: typename boost::multi_index::index<ArrowSet,sourceColor>::type::iterator arrowIter;
312: iterator(const typename boost::multi_index::index<ArrowSet,sourceColor>::type::iterator& iter) {
313: this->arrowIter = typename boost::multi_index::index<ArrowSet,sourceColor>::type::iterator(iter);
314: };
315: virtual ~iterator() {};
316: //
317: virtual iterator operator++() {++this->arrowIter; return *this;};
318: virtual iterator operator++(int n) {iterator tmp(this->arrowIter); ++this->arrowIter; return tmp;};
319: virtual bool operator==(const iterator& itor) const {return this->arrowIter == itor.arrowIter;};
320: virtual bool operator!=(const iterator& itor) const {return this->arrowIter != itor.arrowIter;};
321: virtual const target_type& operator*() const {return this->arrowIter->target;};
322: };
324: supportSequence(const typename ::boost::multi_index::index<ArrowSet,sourceColor>::type& support, const source_type& p) : supportIndex(support), key(p), color(color_type()), useColor(0) {};
325: supportSequence(const typename ::boost::multi_index::index<ArrowSet,sourceColor>::type& support, const source_type& p, const color_type& c) : supportIndex(support), key(p), color(c), useColor(1) {};
326: virtual ~supportSequence() {};
327: virtual iterator begin() {
328: if (useColor) {
329: return iterator(this->supportIndex.lower_bound(::boost::make_tuple(key,color)));
330: } else {
331: return iterator(this->supportIndex.lower_bound(::boost::make_tuple(key)));
332: }
333: };
334: virtual iterator end() {
335: if (useColor) {
336: return iterator(this->supportIndex.upper_bound(::boost::make_tuple(key,color)));
337: } else {
338: return iterator(this->supportIndex.upper_bound(::boost::make_tuple(key)));
339: }
340: };
341: virtual std::size_t size() {
342: if (useColor) {
343: return this->supportIndex.count(::boost::make_tuple(key,color));
344: } else {
345: return this->supportIndex.count(::boost::make_tuple(key));
346: }
347: };
348: };
349: typedef std::set<source_type, std::less<source_type>, ALE_ALLOCATOR<source_type> > coneSet;
350: typedef std::set<target_type, std::less<target_type>, ALE_ALLOCATOR<target_type> > supportSet;
351: // Completion types (some redundant)
352: // Color of completions; encodes the color of the completed BiGraph as well as the rank of the process that contributed arrow.
353: typedef std::pair<color_type, int> completion_color_type;
354: typedef BiGraph<source_type, target_type, completion_color_type> completion_type;
355: // Query methods
356: Obj<capSequence> cap() {
357: return capSequence(::boost::multi_index::get<outdegree>(this->strata));
358: };
359: Obj<baseSequence> base() {
360: return baseSequence(::boost::multi_index::get<indegree>(this->strata));
361: };
362: Obj<coneSequence> cone(const target_type& p) {
363: return coneSequence(::boost::multi_index::get<targetColor>(this->arrows), p);
364: }
365: template<class InputSequence> Obj<coneSet> cone(const Obj<InputSequence>& points) {
366: return this->cone(points, color_type(), false);
367: };
368: Obj<coneSequence> cone(const target_type& p, const color_type& color) {
369: return coneSequence(::boost::multi_index::get<targetColor>(this->arrows), p, color);
370: };
371: template<class InputSequence>
372: Obj<coneSet> cone(const Obj<InputSequence>& points, const color_type& color, bool useColor = true) {
373: Obj<coneSet> cone = coneSet();
375: for(typename InputSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
376: Obj<coneSequence> pCone;
378: if (useColor) {
379: pCone = this->cone(*p_itor, color);
380: } else {
381: pCone = this->cone(*p_itor);
382: }
383: cone->insert(pCone->begin(), pCone->end());
384: }
385: return cone;
386: };
387: Obj<supportSequence> support(const source_type& p) {
388: return supportSequence(::boost::multi_index::get<sourceColor>(this->arrows), p);
389: };
390: Obj<supportSequence> support(const source_type& p, const color_type& color) {
391: return supportSequence(::boost::multi_index::get<sourceColor>(this->arrows), p, color);
392: };
393: template<class sourceInputSequence>
394: Obj<supportSet> support(const Obj<sourceInputSequence>& sources);
395: template<class sourceInputSequence>
396: Obj<supportSet> support(const Obj<sourceInputSequence>& sources, const color_type& color);
397: bool supportContains(const source_type& p, const target_type& q) {
398: //FIX: Shouldn't we just be able to query an arrow?
399: Obj<supportSequence> support = this->support(p);
400:
401: for(typename supportSequence::iterator s_iter = support->begin(); s_iter != support->end(); s_iter++) {
402: if (*s_iter == q) return true;
403: }
404: return false;
405: }
406: // Lattice queries
407: template<class targetInputSequence>
408: Obj<coneSequence> meet(const Obj<targetInputSequence>& targets);
409: template<class targetInputSequence>
410: Obj<coneSequence> meet(const Obj<targetInputSequence>& targets, const color_type& color);
411: template<class sourceInputSequence>
412: Obj<coneSequence> join(const Obj<sourceInputSequence>& sources);
413: template<class sourceInputSequence>
414: Obj<coneSequence> join(const Obj<sourceInputSequence>& sources, const color_type& color);
415: // Manipulation
416: void clear() {
417: this->arrows.clear();
418: this->strata.clear();
419: };
420: void addArrow(const source_type& p, const target_type& q) {
421: this->addArrow(p, q, color_type());
422: };
423: void addArrow(const source_type& p, const target_type& q, const color_type& color) {
424: this->arrows.insert(Arrow_(p, q, color));
425: //std::cout << "Added " << Arrow_(p, q, color);
426: };
427: void addCone(const source_type& source, const target_type& target){
428: this->addArrow(source, target);
429: };
430: template<class sourceInputSequence>
431: void addCone(const Obj<sourceInputSequence>& sources, const target_type& target) {
432: this->addCone(sources, target, color_type());
433: };
434: void addCone(const source_type& source, const target_type& target, const color_type& color) {
435: this->addArrow(source, target, color);
436: };
437: template<class sourceInputSequence>
438: void addCone(const Obj<sourceInputSequence>& sources, const target_type& target, const color_type& color) {
439: if (debug) {std::cout << "Adding a cone " << std::endl;}
440: for(typename sourceInputSequence::iterator iter = sources->begin(); iter != sources->end(); ++iter) {
441: if (debug) {std::cout << "Adding arrow from " << *iter << " to " << target << "(" << color << ")" << std::endl;}
442: this->addArrow(*iter, target, color);
443: }
444: };
445: private:
446: void __clearCone(const target_type& p, const color_type& color, bool useColor) {
447: typename ::boost::multi_index::index<ArrowSet,targetColor>::type& coneIndex = ::boost::multi_index::get<targetColor>(this->arrows);
448: if (useColor) {
449: coneIndex.erase(coneIndex.lower_bound(::boost::make_tuple(p,color)), coneIndex.upper_bound(::boost::make_tuple(p,color)));
450: } else {
451: coneIndex.erase(coneIndex.lower_bound(::boost::make_tuple(p)), coneIndex.upper_bound(::boost::make_tuple(p)));
452: }
453: }
454: public:
455: void setCone(const source_type& source, const target_type& target){
456: this->__clearCone(target, color_type(), false);
457: this->addCone(source, target);
458: };
459: template<class sourceInputSequence>
460: void setCone(const Obj<sourceInputSequence>& sources, const target_type& target) {
461: this->__clearCone(target, color_type(), false);
462: this->addCone(sources, target, color_type());
463: };
464: void setCone(const source_type& source, const target_type& target, const color_type& color) {
465: this->__clearCone(target, color, true);
466: this->addCone(source, target, color);
467: };
468: template<class sourceInputSequence>
469: void setCone(const Obj<sourceInputSequence>& sources, const target_type& target, const color_type& color) {
470: this->__clearCone(target, color, true);
471: this->addCone(sources, target, color);
472: };
473: template<class targetInputSequence>
474: void addSupport(const source_type& source, const Obj<targetInputSequence >& targets);
475: template<class targetInputSequence>
476: void addSupport(const source_type& source, const Obj<targetInputSequence >& targets, const color_type& color);
477: void add(const Obj<BiGraph<source_type, target_type, color_type> >& bigraph);
478: private:
479: struct changeSource {
480: changeSource(source_type newSource) : newSource(newSource) {};
482: void operator()(Arrow_& p) {
483: p.source = newSource;
484: }
485: private:
486: source_type newSource;
487: };
488: public:
489: void replaceSource(const source_type& s, const source_type& new_s) {
490: typename ::boost::multi_index::index<ArrowSet,source>::type& index = ::boost::multi_index::get<source>(this->arrows);
491: typename ::boost::multi_index::index<ArrowSet,source>::type::iterator i = index.find(s);
492: if (i != index.end()) {
493: index.modify(i, changeSource(new_s));
494: } else {
495: std::cout << "ERROR: Could not replace source " << s << " with " << new_s << std::endl;
496: }
497: };
498: private:
499: struct changeTarget {
500: changeTarget(target_type newTarget) : newTarget(newTarget) {};
502: void operator()(Arrow_& p) {
503: p.target = newTarget;
504: }
505: private:
506: target_type newTarget;
507: };
508: public:
509: void replaceTarget(const target_type& t, const target_type& new_t) {
510: typename ::boost::multi_index::index<ArrowSet,target>::type& index = ::boost::multi_index::get<target>(this->arrows);
511: typename ::boost::multi_index::index<ArrowSet,target>::type::iterator i = index.find(t);
512: if (i != index.end()) {
513: index.modify(i, changeTarget(new_t));
514: } else {
515: std::cout << "ERROR: Could not replace target " << t << " with " << new_t << std::endl;
516: }
517: };
518: void replaceSourceOfTarget(const target_type& t, const target_type& new_s) {
519: typename ::boost::multi_index::index<ArrowSet,target>::type& index = ::boost::multi_index::get<target>(this->arrows);
520: typename ::boost::multi_index::index<ArrowSet,target>::type::iterator i = index.find(t);
521: if (i != index.end()) {
522: index.modify(i, changeSource(new_s));
523: } else {
524: std::cout << "ERROR: Could not replace source of target" << t << " with " << new_s << std::endl;
525: }
526: }
527: private:
528: struct changeColor {
529: changeColor(color_type newColor) : newColor(newColor) {};
531: void operator()(Arrow_& p) {
532: p.color = newColor;
533: }
534: private:
535: color_type newColor;
536: };
537: public:
538: bool replaceSourceColor(const source_type& p, const color_type& newColor) {
539: typename ::boost::multi_index::index<ArrowSet,source>::type& index = ::boost::multi_index::get<source>(this->arrows);
540: typename ::boost::multi_index::index<ArrowSet,source>::type::iterator i = index.find(p);
541: if (i != index.end()) {
542: index.modify(i, changeColor(newColor));
543: } else {
544: return false;
545: }
546: return true;
547: };
548: // Structural methods
551: void stratify() {
552: ALE_LOG_EVENT_BEGIN;
553: std::cout << "Stratifying" << std::endl;
554: this->__computeDegrees();
555: ALE_LOG_EVENT_END;
556: }
557: private:
558: struct changeIndegree {
559: changeIndegree(int newIndegree) : newIndegree(newIndegree) {};
561: void operator()(StratumPoint& p) {
562: p.indegree = newIndegree;
563: }
564: private:
565: int newIndegree;
566: };
567: struct changeOutdegree {
568: changeOutdegree(int newOutdegree) : newOutdegree(newOutdegree) {};
570: void operator()(StratumPoint& p) {
571: p.outdegree = newOutdegree;
572: }
573: private:
574: int newOutdegree;
575: };
576: void __computeDegrees() {
577: const typename ::boost::multi_index::index<ArrowSet,target>::type& cones = ::boost::multi_index::get<target>(this->arrows);
578: #if 0
579: const typename ::boost::multi_index::index<ArrowSet,source>::type& supports = ::boost::multi_index::get<source>(this->arrows);
580: #endif
581: typename ::boost::multi_index::index<StratumSet,point>::type& points = ::boost::multi_index::get<point>(this->strata);
583: for(typename ::boost::multi_index::index<ArrowSet,target>::type::iterator c_iter = cones.begin(); c_iter != cones.end(); ++c_iter) {
584: if (points.find(c_iter->target) != points.end()) {
585: typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = points.find(c_iter->target);
587: points.modify(i, changeIndegree(cones.count(c_iter->target)));
588: } else {
589: StratumPoint p;
591: p.point = c_iter->target;
592: p.indegree = cones.count(c_iter->target);
593: this->strata.insert(p);
594: }
595: }
597: #if 0
598: for(typename ::boost::multi_index::index<ArrowSet,source>::type::iterator s_iter = supports.begin(); s_iter != supports.end(); ++s_iter) {
599: if (points.find(s_iter->source) != points.end()) {
600: typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = points.find(s_iter->source);
602: points.modify(i, changeOutdegree(supports.count(s_iter->source)));
603: } else {
604: StratumPoint p;
606: p.point = s_iter->source;
607: p.outdegree = supports.count(s_iter->source);
608: this->strata.insert(p);
609: }
610: }
611: #endif
612: };
613: public:
614: // Parallelism
615: // Compute the cone completion and return it in a separate BiGraph with arrows labeled by completion_color_type colors.
616: Obj<completion_type> coneCompletion();
617: // Compute the support completion and return it in a separate BiGraph with arrows labeled by completion_color_type colors.
618: Obj<completion_type> supportCompletion();
619: // Merge the BiGraph with the provided completion; do nothing if the completion is Null
620: void complete(const Obj<completion_type>& completion);
621: // Merge the BiGraph with the provided completion or compute a cone completion and merge with it, if a Null completion provided
622: void coneComplete(const Obj<completion_type>& completion = Obj<completion_type>());
623: // Merge the BiGraph with the provided completion or compute a support completion and merge with it, if a Null completion provided
624: void supportComplete(const Obj<completion_type>& completion = Obj<completion_type>());
625: };
627: //
628: // Sieve:
629: // A Sieve is a set of {\emph arrows} connecting {\emph points} of type Point_. Thus we
630: // could realize a sieve, for instance, as a directed graph. In addition, we will often
631: // assume an acyclicity constraint, arriving at a DAG. Each arrow may also carry a label,
632: // or {\emph color} of type Color_, and the interface allows sets of arrows to be filtered
633: // by color.
634: //
635: template <typename Point_, typename Color_>
636: class Sieve { // class Sieve
637: public:
638: typedef Color_ color_type;
639: typedef Point_ point_type;
640: typedef int marker_type;
641: int debug;
642: private:
643: // Arrow query tags
644: struct source{};
645: struct target{};
646: struct color{};
647: struct sourceColor{};
648: struct targetColor{};
649: // Arrow structures
650: typedef Arrow<Point,Point,Color_> Arrow_;
651: typedef ::boost::multi_index::multi_index_container<
652: Arrow_,
653: ::boost::multi_index::indexed_by<
654: ::boost::multi_index::ordered_non_unique<
655: ::boost::multi_index::tag<source>, BOOST_MULTI_INDEX_MEMBER(Arrow_,Point_,source)>,
656: ::boost::multi_index::ordered_non_unique<
657: ::boost::multi_index::tag<target>, BOOST_MULTI_INDEX_MEMBER(Arrow_,Point_,target)>,
658: ::boost::multi_index::ordered_non_unique<
659: ::boost::multi_index::tag<color>, BOOST_MULTI_INDEX_MEMBER(Arrow_,Color_,color)>,
660: ::boost::multi_index::ordered_non_unique<
661: ::boost::multi_index::tag<sourceColor>,
662: ::boost::multi_index::composite_key<
663: Arrow_, BOOST_MULTI_INDEX_MEMBER(Arrow_,Point_,source), BOOST_MULTI_INDEX_MEMBER(Arrow_,Color_,color)>
664: >,
665: ::boost::multi_index::ordered_non_unique<
666: ::boost::multi_index::tag<targetColor>,
667: ::boost::multi_index::composite_key<
668: Arrow_, BOOST_MULTI_INDEX_MEMBER(Arrow_,Point_,target), BOOST_MULTI_INDEX_MEMBER(Arrow_,Color_,color)>
669: >
670: >,
671: ALE_ALLOCATOR<Arrow_>
672: > ArrowSet;
673: ArrowSet arrows;
675: // Stratum query tags
676: // Could eliminate some sequences
677: struct point{};
678: struct depthTag{};
679: struct heightTag{};
680: struct indegree{};
681: struct outdegree{};
682: struct marker{};
683: struct heightMarker{};
684: struct depthMarker{};
685: // Stratum stuctures
686: struct StratumPoint {
687: Point_ point;
688: int depth;
689: int height;
690: int indegree;
691: int outdegree;
692: marker_type marker;
694: StratumPoint() : depth(0), height(0), indegree(0), outdegree(0), marker(marker_type()) {};
695: StratumPoint(const Point_& p) : point(p), depth(0), height(0), indegree(0), outdegree(0), marker(marker_type()) {};
696: // Printing
697: friend std::ostream& operator<<(std::ostream& os, const StratumPoint& p) {
698: os << "[" << p.point << ", "<< p.depth << ", "<< p.height << ", "<< p.indegree << ", "<< p.outdegree << ", " << p.marker << "]";
699: return os;
700: };
701: };
702: typedef ::boost::multi_index::multi_index_container<
703: StratumPoint,
704: ::boost::multi_index::indexed_by<
705: ::boost::multi_index::ordered_unique<
706: ::boost::multi_index::tag<point>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,Point_,point)>,
707: ::boost::multi_index::ordered_non_unique<
708: ::boost::multi_index::tag<depthTag>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,depth)>,
709: ::boost::multi_index::ordered_non_unique<
710: ::boost::multi_index::tag<heightTag>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,height)>,
711: ::boost::multi_index::ordered_non_unique<
712: ::boost::multi_index::tag<indegree>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,indegree)>,
713: ::boost::multi_index::ordered_non_unique<
714: ::boost::multi_index::tag<outdegree>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,outdegree)>,
715: ::boost::multi_index::ordered_non_unique<
716: ::boost::multi_index::tag<marker>, BOOST_MULTI_INDEX_MEMBER(StratumPoint,marker_type,marker)>,
717: ::boost::multi_index::ordered_non_unique<
718: ::boost::multi_index::tag<depthMarker>,
719: ::boost::multi_index::composite_key<
720: StratumPoint, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,depth), BOOST_MULTI_INDEX_MEMBER(StratumPoint,marker_type,marker)>
721: >,
722: ::boost::multi_index::ordered_non_unique<
723: ::boost::multi_index::tag<heightMarker>,
724: ::boost::multi_index::composite_key<
725: StratumPoint, BOOST_MULTI_INDEX_MEMBER(StratumPoint,int,height), BOOST_MULTI_INDEX_MEMBER(StratumPoint,marker_type,marker)>
726: >
727: >,
728: ALE_ALLOCATOR<StratumPoint>
729: > StratumSet;
731: StratumSet strata;
732: bool stratification;
733: int maxDepth;
734: int maxHeight;
735: int graphDiameter;
736: public:
737: //
738: // Output sequence types
739: //
741: class baseSequence {
742: const typename ::boost::multi_index::index<StratumSet,indegree>::type& baseIndex;
743: public:
744: class iterator {
745: public:
746: typedef std::input_iterator_tag iterator_category;
747: typedef Point_ value_type;
748: typedef int difference_type;
749: typedef Point_* pointer;
750: typedef Point_& reference;
751: typename boost::multi_index::index<StratumSet,indegree>::type::iterator pointIter;
752:
753: iterator(const typename boost::multi_index::index<StratumSet,indegree>::type::iterator& iter) {
754: this->pointIter = typename boost::multi_index::index<StratumSet,indegree>::type::iterator(iter);
755: };
756: virtual ~iterator() {};
757: //
758: virtual iterator operator++() {++this->pointIter; return *this;};
759: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
760: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
761: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
762: virtual const Point_& operator*() const {return this->pointIter->point;};
763: };
764: baseSequence(const typename ::boost::multi_index::index<StratumSet,indegree>::type& base) : baseIndex(base) {};
765: virtual ~baseSequence() {};
766: virtual iterator begin() {return iterator(this->baseIndex.upper_bound(0));};
767: virtual iterator end() {return iterator(this->baseIndex.end());};
768: virtual std::size_t size() {return -1;};
769: };
771: class capSequence {
772: const typename ::boost::multi_index::index<StratumSet,outdegree>::type& capIndex;
773: public:
774: class iterator {
775: public:
776: typedef std::input_iterator_tag iterator_category;
777: typedef Point_ value_type;
778: typedef int difference_type;
779: typedef Point_* pointer;
780: typedef Point_& reference;
781: typename boost::multi_index::index<StratumSet,outdegree>::type::iterator pointIter;
782:
783: iterator(const typename boost::multi_index::index<StratumSet,outdegree>::type::iterator& iter) {
784: this->pointIter = typename boost::multi_index::index<StratumSet,outdegree>::type::iterator(iter);
785: };
786: virtual ~iterator() {};
787: //
788: virtual iterator operator++() {++this->pointIter; return *this;};
789: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
790: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
791: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
792: virtual const Point_& operator*() const {return this->pointIter->point;};
793: };
794: capSequence(const typename ::boost::multi_index::index<StratumSet,outdegree>::type& cap) : capIndex(cap) {};
795: virtual ~capSequence() {};
796: virtual iterator begin() {return iterator(this->capIndex.upper_bound(0));};
797: virtual iterator end() {return iterator(this->capIndex.end());};
798: virtual std::size_t size() {return -1;};
799: };
801: class rootSequence {
802: const typename ::boost::multi_index::index<StratumSet,indegree>::type& rootIndex;
803: public:
804: class iterator {
805: public:
806: typedef std::input_iterator_tag iterator_category;
807: typedef Point_ value_type;
808: typedef int difference_type;
809: typedef Point_* pointer;
810: typedef Point_& reference;
811: typename boost::multi_index::index<StratumSet,indegree>::type::iterator pointIter;
812:
813: iterator(const typename boost::multi_index::index<StratumSet,indegree>::type::iterator& iter){
814: this->pointIter = typename boost::multi_index::index<StratumSet,indegree>::type::iterator(iter);
815: };
816: virtual ~iterator() {};
817: //
818: virtual iterator operator++() {++this->pointIter; return *this;};
819: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
820: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
821: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
822: virtual const Point_& operator*() const {return this->pointIter->point;};
823: };
824: rootSequence(const typename ::boost::multi_index::index<StratumSet,indegree>::type& root) : rootIndex(root) {};
825: virtual ~rootSequence() {};
826: virtual iterator begin() {return iterator(this->rootIndex.lower_bound(0));};
827: virtual iterator end() {return iterator(this->rootIndex.upper_bound(0));};
828: virtual std::size_t size() {return this->rootIndex.count(0);};
829: };
830:
831: class leafSequence {
832: const typename ::boost::multi_index::index<StratumSet,outdegree>::type& leafIndex;
833: public:
834: class iterator {
835: public:
836: typedef std::input_iterator_tag iterator_category;
837: typedef Point_ value_type;
838: typedef int difference_type;
839: typedef Point_* pointer;
840: typedef Point_& reference;
841: typename boost::multi_index::index<StratumSet,outdegree>::type::iterator pointIter;
842:
843: iterator(const typename boost::multi_index::index<StratumSet,outdegree>::type::iterator& iter) {
844: this->pointIter = typename boost::multi_index::index<StratumSet,outdegree>::type::iterator(iter);
845: };
846: virtual ~iterator() {};
847: //
848: virtual iterator operator++() {++this->pointIter; return *this;};
849: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
850: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
851: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
852: virtual const Point_& operator*() const {return this->pointIter->point;};
853: };
854:
855: leafSequence(const typename ::boost::multi_index::index<StratumSet,outdegree>::type& leaf) : leafIndex(leaf) {};
856: virtual ~leafSequence() {};
857: virtual iterator begin() {return iterator(this->leafIndex.lower_bound(0));};
858: virtual iterator end() {return iterator(this->leafIndex.upper_bound(0));};
859: virtual std::size_t size() {return this->leafIndex.count(0);};
860: };
861:
862: class coneSequence {
863: typename ::boost::multi_index::index<ArrowSet,targetColor>::type& coneIndex;
864: const Point_ key;
865: const Color_ color;
866: const bool useColor;
867: struct changeColor {
868: changeColor(color_type newColor) : newColor(newColor) {};
870: void operator()(Arrow_& p) {
871: p.color = newColor;
872: }
873: private:
874: color_type newColor;
875: };
876: public:
877: class iterator {
878: typename ::boost::multi_index::index<ArrowSet,targetColor>::type& index;
879: public:
880: typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator arrowIter;
881:
882: iterator(typename ::boost::multi_index::index<ArrowSet,targetColor>::type& index, const typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator& iter) : index(index) {
883: this->arrowIter = typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator(iter);
884: };
885: virtual ~iterator() {};
886: //
887: virtual iterator operator++() {++this->arrowIter; return *this;};
888: virtual iterator operator++(int n) {iterator tmp(this->index, this->arrowIter); ++this->arrowIter; return tmp;};
889: virtual iterator operator--() {--this->arrowIter; return *this;};
890: virtual iterator operator--(int n) {iterator tmp(this->index, this->arrowIter); --this->arrowIter; return tmp;};
891: virtual bool operator==(const iterator& itor) const {return this->arrowIter == itor.arrowIter;};
892: virtual bool operator!=(const iterator& itor) const {return this->arrowIter != itor.arrowIter;};
893: virtual const Point_& operator*() const {return this->arrowIter->source;};
894: void setColor(int newColor) {this->index.modify(this->arrowIter, changeColor(newColor));};
895: };
896: class reverse_iterator {
897: public:
898: typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator arrowIter;
899:
900: reverse_iterator(const typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator& iter) {
901: this->arrowIter = typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator(iter);
902: };
903: virtual ~reverse_iterator() {};
904: //
905: virtual reverse_iterator operator++() {--this->arrowIter; return *this;};
906: virtual reverse_iterator operator++(int n) {reverse_iterator tmp(this->arrowIter); --this->arrowIter; return tmp;};
907: virtual bool operator==(const reverse_iterator& itor) const {return this->arrowIter == itor.arrowIter;};
908: virtual bool operator!=(const reverse_iterator& itor) const {return this->arrowIter != itor.arrowIter;};
909: virtual const Point_& operator*() const {return this->arrowIter->source;};
910: };
911:
912: coneSequence(typename ::boost::multi_index::index<ArrowSet,targetColor>::type& cone, const Point_& p) :
913: coneIndex(cone), key(p), color(Color_()), useColor(0) {};
914: coneSequence(typename ::boost::multi_index::index<ArrowSet,targetColor>::type& cone, const Point_& p, const Color_& c) :
915: coneIndex(cone), key(p), color(c), useColor(1) {};
916: virtual ~coneSequence() {};
917: virtual iterator begin() {
918: if (useColor) {
919: return iterator(this->coneIndex, this->coneIndex.lower_bound(::boost::make_tuple(key,color)));
920: } else {
921: return iterator(this->coneIndex, this->coneIndex.lower_bound(::boost::make_tuple(key)));
922: }
923: };
924: virtual iterator end() {
925: if (useColor) {
926: return iterator(this->coneIndex, this->coneIndex.upper_bound(::boost::make_tuple(key,color)));
927: } else {
928: return iterator(this->coneIndex, this->coneIndex.upper_bound(::boost::make_tuple(key)));
929: }
930: };
931: virtual reverse_iterator rbegin() {
932: if (useColor) {
933: return reverse_iterator(--this->coneIndex.upper_bound(::boost::make_tuple(key,color)));
934: } else {
935: return reverse_iterator(--this->coneIndex.upper_bound(::boost::make_tuple(key)));
936: }
937: };
938: virtual reverse_iterator rend() {
939: typename boost::multi_index::index<ArrowSet,targetColor>::type::iterator i;
940:
941: if (useColor) {
942: return reverse_iterator(--this->coneIndex.lower_bound(::boost::make_tuple(key,color)));
943: } else {
944: return reverse_iterator(--this->coneIndex.lower_bound(::boost::make_tuple(key)));
945: }
946: };
947: virtual std::size_t size() {
948: if (useColor) {
949: return this->coneIndex.count(::boost::make_tuple(key,color));
950: } else {
951: return this->coneIndex.count(::boost::make_tuple(key));
952: }
953: };
954: }; // class Sieve<Point_,Color_>::coneSequence
955:
956: class supportSequence {
957: const typename ::boost::multi_index::index<ArrowSet,sourceColor>::type& supportIndex;
958: const Point_ key;
959: const Color_ color;
960: const bool useColor;
961: public:
962: class iterator {
963: public:
964: typename boost::multi_index::index<ArrowSet,sourceColor>::type::iterator arrowIter;
965:
966: iterator(const typename boost::multi_index::index<ArrowSet,sourceColor>::type::iterator& iter) {
967: this->arrowIter = typename boost::multi_index::index<ArrowSet,sourceColor>::type::iterator(iter);
968: };
969: virtual ~iterator() {};
970: //
971: virtual iterator operator++() {++this->arrowIter; return *this;};
972: virtual iterator operator++(int n) {iterator tmp(this->arrowIter); ++this->arrowIter; return tmp;};
973: virtual bool operator==(const iterator& itor) const {return this->arrowIter == itor.arrowIter;};
974: virtual bool operator!=(const iterator& itor) const {return this->arrowIter != itor.arrowIter;};
975: virtual const Point_& operator*() const {return this->arrowIter->target;};
976: };
977:
978: supportSequence(const typename ::boost::multi_index::index<ArrowSet,sourceColor>::type& support, const Point_& p)
979: : supportIndex(support), key(p), color(Color_()), useColor(0) {};
980: supportSequence(const typename ::boost::multi_index::index<ArrowSet,sourceColor>::type& support,const Point_& p,const Color_& c)
981: : supportIndex(support), key(p), color(c), useColor(1) {};
982: virtual ~supportSequence() {};
983: virtual iterator begin() {
984: if (useColor) {
985: return iterator(this->supportIndex.lower_bound(::boost::make_tuple(key,color)));
986: } else {
987: return iterator(this->supportIndex.lower_bound(::boost::make_tuple(key)));
988: }
989: };
990: virtual iterator end() {
991: if (useColor) {
992: return iterator(this->supportIndex.upper_bound(::boost::make_tuple(key,color)));
993: } else {
994: return iterator(this->supportIndex.upper_bound(::boost::make_tuple(key)));
995: }
996: };
997: virtual std::size_t size() {
998: if (useColor) {
999: return this->supportIndex.count(::boost::make_tuple(key,color));
1000: } else {
1001: return this->supportIndex.count(::boost::make_tuple(key));
1002: }
1003: };
1004: };
1007: class depthSequence {
1008: const typename ::boost::multi_index::index<StratumSet,depthTag>::type& depthIndex;
1009: const int d;
1010: public:
1011: class iterator {
1012: public:
1013: typedef std::input_iterator_tag iterator_category;
1014: typedef Point_ value_type;
1015: typedef int difference_type;
1016: typedef Point_* pointer;
1017: typedef Point_& reference;
1018: typename boost::multi_index::index<StratumSet,depthTag>::type::iterator pointIter;
1020: iterator(const typename boost::multi_index::index<StratumSet,depthTag>::type::iterator& iter) {
1021: this->pointIter = typename boost::multi_index::index<StratumSet,depthTag>::type::iterator(iter);
1022: };
1023: virtual ~iterator() {};
1024: //
1025: virtual iterator operator++() {++this->pointIter; return *this;};
1026: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
1027: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
1028: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
1029: virtual const Point_& operator*() const {return this->pointIter->point;};
1030: marker_type getMarker() const {return this->pointIter->marker;};
1031: };
1033: depthSequence(const typename ::boost::multi_index::index<StratumSet,depthTag>::type& depthIndex, const int d) : depthIndex(depthIndex), d(d) {};
1034: virtual ~depthSequence() {};
1035: virtual iterator begin() {return iterator(this->depthIndex.lower_bound(d));};
1036: virtual iterator end() {return iterator(this->depthIndex.upper_bound(d));};
1037: virtual std::size_t size() {return this->depthIndex.count(d);};
1038: };
1040: class heightSequence {
1041: const typename ::boost::multi_index::index<StratumSet,heightTag>::type& heightIndex;
1042: const int h;
1043: public:
1044: class iterator {
1045: public:
1046: typedef std::input_iterator_tag iterator_category;
1047: typedef Point_ value_type;
1048: typedef int difference_type;
1049: typedef Point_* pointer;
1050: typedef Point_& reference;
1051: typename boost::multi_index::index<StratumSet,heightTag>::type::iterator pointIter;
1052:
1053: iterator(const typename boost::multi_index::index<StratumSet,heightTag>::type::iterator& iter) {
1054: this->pointIter = typename boost::multi_index::index<StratumSet,heightTag>::type::iterator(iter);
1055: };
1056: virtual ~iterator() {};
1057: //
1058: virtual iterator operator++() {++this->pointIter; return *this;};
1059: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
1060: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
1061: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
1062: virtual const Point_& operator*() const {return this->pointIter->point;};
1063: marker_type getMarker() const {return this->pointIter->marker;};
1064: };
1065:
1066: heightSequence(const typename ::boost::multi_index::index<StratumSet,heightTag>::type& height, const int h) :
1067: heightIndex(height), h(h) {};
1068: virtual ~heightSequence() {};
1069: virtual iterator begin() {return iterator(this->heightIndex.lower_bound(h));};
1070: virtual iterator end() {return iterator(this->heightIndex.upper_bound(h));};
1071: virtual std::size_t size() {return this->heightIndex.count(h);};
1072: };
1073:
1074: class markerSequence {
1075: const typename ::boost::multi_index::index<StratumSet,marker>::type& markerIndex;
1076: const marker_type m;
1077: public:
1078: class iterator {
1079: public:
1080: typedef std::input_iterator_tag iterator_category;
1081: typedef Point_ value_type;
1082: typedef int difference_type;
1083: typedef Point_* pointer;
1084: typedef Point_& reference;
1085: typename boost::multi_index::index<StratumSet,marker>::type::iterator pointIter;
1087: iterator(const typename boost::multi_index::index<StratumSet,marker>::type::iterator& iter) {
1088: this->pointIter = typename boost::multi_index::index<StratumSet,marker>::type::iterator(iter);
1089: };
1090: virtual ~iterator() {};
1091: //
1092: virtual iterator operator++() {++this->pointIter; return *this;};
1093: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
1094: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
1095: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
1096: virtual const Point_& operator*() const {return this->pointIter->point;};
1097: };
1099: markerSequence(const typename ::boost::multi_index::index<StratumSet,marker>::type& marker, const marker_type m) : markerIndex(marker), m(m) {};
1100: virtual ~markerSequence() {};
1101: virtual iterator begin() {return iterator(this->markerIndex.lower_bound(m));};
1102: virtual iterator end() {return iterator(this->markerIndex.upper_bound(m));};
1103: virtual std::size_t size() {return this->markerIndex.count(m);};
1104: };
1106: class depthMarkerSequence {
1107: const typename ::boost::multi_index::index<StratumSet,depthMarker>::type& markerIndex;
1108: const int depth;
1109: const marker_type m;
1110: const bool useMarker;
1111: public:
1112: class iterator {
1113: public:
1114: typedef std::input_iterator_tag iterator_category;
1115: typedef Point_ value_type;
1116: typedef int difference_type;
1117: typedef Point_* pointer;
1118: typedef Point_& reference;
1119: typename boost::multi_index::index<StratumSet,depthMarker>::type::iterator pointIter;
1121: iterator(const typename boost::multi_index::index<StratumSet,depthMarker>::type::iterator& iter) {
1122: this->pointIter = typename boost::multi_index::index<StratumSet,depthMarker>::type::iterator(iter);
1123: };
1124: virtual ~iterator() {};
1125: //
1126: virtual iterator operator++() {++this->pointIter; return *this;};
1127: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
1128: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
1129: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
1130: virtual const Point_ & operator*() const {return this->pointIter->point;};
1131: marker_type getMarker() const {return this->pointIter->marker;};
1132: };
1134: depthMarkerSequence(const typename ::boost::multi_index::index<StratumSet,depthMarker>::type& marker, const int depth) : markerIndex(marker), depth(depth), m(marker_type()), useMarker(false) {};
1135: depthMarkerSequence(const typename ::boost::multi_index::index<StratumSet,depthMarker>::type& marker, const int depth, const marker_type m) : markerIndex(marker), depth(depth), m(m), useMarker(true) {};
1136: virtual ~depthMarkerSequence() {};
1137: virtual iterator begin() {
1138: if (useMarker) {
1139: return iterator(this->markerIndex.lower_bound(::boost::make_tuple(depth,m)));
1140: } else {
1141: return iterator(this->markerIndex.lower_bound(::boost::make_tuple(depth)));
1142: }
1143: };
1144: virtual iterator end() {
1145: if (useMarker) {
1146: return iterator(this->markerIndex.upper_bound(::boost::make_tuple(depth,m)));
1147: } else {
1148: return iterator(this->markerIndex.upper_bound(::boost::make_tuple(depth)));
1149: }
1150: };
1151: virtual std::size_t size() {
1152: if (useMarker) {
1153: return this->markerIndex.count(::boost::make_tuple(depth,m));
1154: } else {
1155: return this->markerIndex.count(::boost::make_tuple(depth));
1156: }
1157: };
1158: };
1160: class heightMarkerSequence {
1161: const typename ::boost::multi_index::index<StratumSet,heightMarker>::type& markerIndex;
1162: const int height;
1163: const marker_type m;
1164: const bool useMarker;
1165: public:
1166: class iterator {
1167: public:
1168: typedef std::input_iterator_tag iterator_category;
1169: typedef Point_ value_type;
1170: typedef int difference_type;
1171: typedef Point_* pointer;
1172: typedef Point_& reference;
1173: typename boost::multi_index::index<StratumSet,heightMarker>::type::iterator pointIter;
1175: iterator(const typename boost::multi_index::index<StratumSet,heightMarker>::type::iterator& iter) {
1176: this->pointIter = typename boost::multi_index::index<StratumSet,heightMarker>::type::iterator(iter);
1177: };
1178: virtual ~iterator() {};
1179: //
1180: virtual iterator operator++() {++this->pointIter; return *this;};
1181: virtual iterator operator++(int n) {iterator tmp(this->pointIter); ++this->pointIter; return tmp;};
1182: virtual bool operator==(const iterator& itor) const {return this->pointIter == itor.pointIter;};
1183: virtual bool operator!=(const iterator& itor) const {return this->pointIter != itor.pointIter;};
1184: virtual const Point_ & operator*() const {return this->pointIter->point;};
1185: marker_type getMarker() const {return this->pointIter->marker;};
1186: };
1188: heightMarkerSequence(const typename ::boost::multi_index::index<StratumSet,marker>::type& marker, const int height) : markerIndex(marker), height(height), m(marker_type()), useMarker(false) {};
1189: heightMarkerSequence(const typename ::boost::multi_index::index<StratumSet,marker>::type& marker, const int height, const marker_type m) : markerIndex(marker), height(height), m(m), useMarker(true) {};
1190: virtual ~heightMarkerSequence() {};
1191: virtual iterator begin() {
1192: if (useMarker) {
1193: return iterator(this->markerIndex.lower_bound(::boost::make_tuple(height,m)));
1194: } else {
1195: return iterator(this->markerIndex.lower_bound(::boost::make_tuple(height)));
1196: }
1197: };
1198: virtual iterator end() {
1199: if (useMarker) {
1200: return iterator(this->markerIndex.upper_bound(::boost::make_tuple(height,m)));
1201: } else {
1202: return iterator(this->markerIndex.upper_bound(::boost::make_tuple(height)));
1203: }
1204: };
1205: virtual std::size_t size() {
1206: if (useMarker) {
1207: return this->markerIndex.count(::boost::make_tuple(height,m));
1208: } else {
1209: return this->markerIndex.count(::boost::make_tuple(height));
1210: }
1211: };
1212: };
1214: public:
1215: Sieve(int debug = 0) : debug(debug), stratification(false), maxDepth(-1), maxHeight(-1), graphDiameter(-1) {};
1216: // Printing
1217: friend std::ostream& operator<<(std::ostream& os, Obj<Sieve<Point_,Color_> > s) {
1218: os << *s;
1219: return os;
1220: };
1221:
1222: friend std::ostream& operator<<(std::ostream& os, Sieve<Point_,Color_>& s) {
1223: Obj<baseSequence> base = s.base();
1224: for(typename baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
1225: Obj<coneSequence> cone = s.cone(*b_iter);
1226: os << "Base point " << *b_iter << " with cone:" << std::endl;
1227: for(typename coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
1228: os << " " << *c_iter << std::endl;
1229: }
1230: }
1231: return os;
1232: };
1234: //friend std::ostream& operator<<(std::ostream& os, Obj<Sieve<Point_,Color_> > s);
1235: //friend std::ostream& operator<<(std::ostream& os, Sieve<Point_,Color_>& s);
1237: public:
1238: //
1239: // The basic Sieve interface
1240: //
1241: void clear();
1243: Obj<coneSequence> cone(const Point_& p);
1245: template<class InputSequence>
1246: Obj<PointSet> cone(const Obj<InputSequence>& points);
1248: Obj<coneSequence> cone(const Point_& p, const Color_& color);
1250: template<class InputSequence>
1251: Obj<PointSet> cone(const Obj<InputSequence>& points, const Color_& color);
1253: Obj<PointArray> nCone(const Point_& p, int n);
1255: Obj<PointArray> nCone(const Point_& p, int n, const Color_& color, bool useColor = true);
1257: template<class InputSequence>
1258: Obj<PointSet> nCone(const Obj<InputSequence>& points, int n);
1260: template<class InputSequence>
1261: Obj<PointSet> nCone(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
1263: bool coneContains(const Point_& p, const Point_& q);
1265: Obj<supportSequence> support(const Point_& p);
1267: template<class InputSequence>
1268: Obj<PointSet> support(const Obj<InputSequence>& points);
1270: Obj<supportSequence> support(const Point_& p, const Color_& color);
1272: template<class InputSequence>
1273: Obj<PointSet> support(const Obj<InputSequence>& points, const Color_& color);
1275: template<class InputSequence>
1276: Obj<PointSet> nSupport(const Obj<InputSequence>& points, int n);
1278: template<class InputSequence>
1279: Obj<PointSet> nSupport(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
1281: bool supportContains(const Point_& q, const Point_& p);
1283: private:
1284: template<class InputSequence> Obj<PointSet>
1285: __nCone(Obj<InputSequence>& cone, int n, const Color_& color, bool useColor);
1287: template<class pointSequence> void
1288: __nCone(const Obj<pointSequence>& cone, int n, const Color_& color, bool useColor, Obj<PointArray> cone, Obj<PointSet> seen);
1289:
1290: public:
1291: //
1292: // Iterated versions
1293: //
1294: Obj<PointSet> closure(const Point_& p);
1296: Obj<PointSet> closure(const Point_& p, const Color_& color);
1298: template<class InputSequence>
1299: Obj<PointSet> closure(const Obj<InputSequence>& points);
1301: template<class InputSequence>
1302: Obj<PointSet> closure(const Obj<InputSequence>& points, const Color_& color);
1304: Obj<PointSet> nClosure(const Point_& p, int n);
1306: Obj<PointSet> nClosure(const Point_& p, int n, const Color_& color, bool useColor = true);
1308: template<class InputSequence>
1309: Obj<PointSet> nClosure(const Obj<InputSequence>& points, int n);
1311: template<class InputSequence>
1312: Obj<PointSet> nClosure(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
1314: Obj<Sieve<Point_,Color_> > closureSieve(const Point_& p);
1316: Obj<Sieve<Point_,Color_> > closureSieve(const Point_& p, const Color_& color);
1318: template<class InputSequence>
1319: Obj<Sieve<Point_,Color_> > closureSieve(const Obj<InputSequence>& points);
1321: template<class InputSequence>
1322: Obj<Sieve<Point_,Color_> > closureSieve(const Obj<InputSequence>& points, const Color_& color);
1324: Obj<Sieve<Point_,Color_> > nClosureSieve(const Point_& p, int n);
1326: Obj<Sieve<Point_,Color_> > nClosureSieve(const Point_& p, int n, const Color_& color, bool useColor = true);
1328: template<class InputSequence>
1329: Obj<Sieve<Point_,Color_> > nClosureSieve(const Obj<InputSequence>& points, int n);
1331: template<class InputSequence>
1332: Obj<Sieve<Point_,Color_> > nClosureSieve(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
1334: Obj<PointSet> star(const Point_& p);
1336: Obj<PointSet> star(const Point_& p, const Color_& color);
1338: template<class InputSequence>
1339: Obj<PointSet> star(const Obj<InputSequence>& points);
1341: template<class InputSequence>
1342: Obj<PointSet> star(const Obj<InputSequence>& points, const Color_& color);
1344: Obj<PointSet> nStar(const Point_& p, int n);
1346: Obj<PointSet> nStar(const Point_& p, int n, const Color_& color, bool useColor = true);
1348: template<class InputSequence>
1349: Obj<PointSet> nStar(const Obj<InputSequence>& points, int n);
1351: template<class InputSequence>
1352: Obj<PointSet> nStar(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
1354: private:
1355: template<class InputSequence>
1356: Obj<PointSet> __nClosure(Obj<InputSequence>& cone, int n, const Color_& color, bool useColor);
1358: template<class InputSequence>
1359: Obj<Sieve<Point_,Color_> > __nClosureSieve(Obj<InputSequence>& cone, int n, const Color_& color, bool useColor);
1361: template<class InputSequence>
1362: Obj<PointSet> __nStar(Obj<InputSequence>& support, int n, const Color_& color, bool useColor);
1364: public:
1365: //
1366: // Lattice methods
1367: //
1368: Obj<PointSet> meet(const Point_& p, const Point_& q);
1370: Obj<PointSet> meet(const Point_& p, const Point_& q, const Color_& color);
1372: template<class InputSequence>
1373: Obj<PointSet> meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1);
1375: template<class InputSequence>
1376: Obj<PointSet> meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color);
1378: Obj<PointSet> nMeet(const Point_& p, const Point_& q, int n);
1380: Obj<PointSet> nMeet(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor = true);
1382: template<class InputSequence>
1383: Obj<PointSet> nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n);
1385: template<class InputSequence>
1386: Obj<PointSet> nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n,
1387: const Color_& color, bool useColor = true);
1389: Obj<PointSet> join(const Point_& p, const Point_& q);
1391: Obj<PointSet> join(const Point_& p, const Point_& q, const Color_& color);
1393: template<class InputSequence>
1394: Obj<PointSet> join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1);
1396: template<class InputSequence>
1397: Obj<PointSet> join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color);
1399: Obj<PointSet> nJoin(const Point_& p, const Point_& q, int n);
1401: Obj<PointSet> nJoin(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor = true);
1403: template<class InputSequence>
1404: Obj<PointSet> nJoin(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n);
1406: template<class InputSequence>
1407: Obj<PointSet> nJoin(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n, const Color_& color, bool useColor = true);
1409: public:
1410: //
1411: // Manipulation
1412: //
1413: void addPoint(const Point_& p);
1415: void addArrow(const Point_& p, const Point_& q);
1417: void addArrow(const Point_& p, const Point_& q, const Color_& color);
1419: template<class InputSequence>
1420: void addCone(const Obj<InputSequence >& points, const Point_& p);
1422: template<class InputSequence>
1423: void addCone(const Obj<InputSequence >& points, const Point_& p, const Color_& color);
1425: template<class InputSequence>
1426: void addSupport(const Point_& p, const Obj<InputSequence >& points);
1428: template<class InputSequence>
1429: void addSupport(const Point_& p, const Obj<InputSequence >& points, const Color_& color);
1431: void add(const Obj<Sieve<Point_,Color_> >& sieve);
1433: public:
1434: //
1435: // Parallelism
1436: //
1437: Obj<std::map<Point_, Sieve<Point_,Color_> > > completion(const Sieve<Point_,Color_>& base);
1439: public:
1440: //
1441: // Views
1442: //
1443: Obj<baseSequence> base() {
1444: return baseSequence(::boost::multi_index::get<indegree>(this->strata));
1445: };
1446: Obj<capSequence> cap() {
1447: return capSequence(::boost::multi_index::get<outdegree>(this->strata));
1448: };
1449: Obj<rootSequence> roots() {
1450: return rootSequence(::boost::multi_index::get<indegree>(this->strata));
1451: };
1452: Obj<leafSequence> leaves() {
1453: return leafSequence(::boost::multi_index::get<outdegree>(this->strata));
1454: };
1456: public:
1457: //
1458: // Structural queries
1459: //
1460: int depth();
1461: int depth(const Point_& p);
1463: template<typename InputSequence>
1464: int depth(const Obj<InputSequence>& points);
1466: int height();
1468: int height(const Point_& p);
1470: template<typename InputSequence>
1471: int height(const Obj<InputSequence>& points);
1473: int diameter();
1475: int diameter(const Point_& p);
1477: Obj<depthSequence> depthStratum(int d);
1479: Obj<depthMarkerSequence> depthStratum(int d, marker_type m);
1481: Obj<heightSequence> heightStratum(int h);
1483: Obj<heightMarkerSequence> heightStratum(int h, marker_type m);
1485: Obj<markerSequence> markerStratum(marker_type m);
1486:
1487: void setStratification(bool doStratify);
1489: bool getStratification();
1491: void stratify(bool show = false);
1494: public:
1495: //
1496: // Structural manipulation
1497: //
1499: struct changeMarker {
1500: changeMarker(int newMarker) : newMarker(newMarker) {};
1502: void operator()(StratumPoint& p) {
1503: p.marker = newMarker;
1504: }
1505: private:
1506: marker_type newMarker;
1507: };
1509: void setMarker(const point_type& p, const marker_type& marker);
1511: template<class InputSequence>
1512: void setMarker(const Obj<InputSequence>& points, const marker_type& marker);
1514: private:
1515: struct changeIndegree {
1516: changeIndegree(int newIndegree) : newIndegree(newIndegree) {};
1518: void operator()(StratumPoint& p) {
1519: p.indegree = newIndegree;
1520: }
1521: private:
1522: int newIndegree;
1523: };
1525: struct changeOutdegree {
1526: changeOutdegree(int newOutdegree) : newOutdegree(newOutdegree) {};
1528: void operator()(StratumPoint& p) {
1529: p.outdegree = newOutdegree;
1530: }
1531: private:
1532: int newOutdegree;
1533: };
1535: void __computeDegrees();
1537: struct changeHeight {
1538: changeHeight(int newHeight) : newHeight(newHeight) {};
1540: void operator()(StratumPoint& p) {
1541: p.height = newHeight;
1542: }
1543: private:
1544: int newHeight;
1545: };
1546:
1547: template<class InputSequence>
1548: void __computeClosureHeights(const Obj<InputSequence>& points);
1550: struct changeDepth {
1551: changeDepth(int newDepth) : newDepth(newDepth) {};
1553: void operator()(StratumPoint& p) {
1554: p.depth = newDepth;
1555: }
1556: private:
1557: int newDepth;
1558: };
1560: template<class InputSequence>
1561: void __computeStarDepths(const Obj<InputSequence>& points);
1563: };//class Sieve
1566: //
1567: // Sieve printing
1568: //
1569:
1570: // template <typename Point_, typename Color_>
1571: // std::ostream& operator<<(std::ostream& os, Obj<Sieve<Point_,Color_> > s) {
1572: // os << *s;
1573: // return os;
1574: // };
1575:
1576: // template <typename Point_, typename Color_>
1577: // std::ostream& operator<<(std::ostream& os, Sieve<Point_,Color_>& s) {
1578: // Obj<Sieve<Point_,Color_>::baseSequence> base = s.base();
1579:
1580: // for(typename baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
1581: // Obj<Sieve<Point_,Color_>::coneSequence> cone = s.cone(*b_iter);
1582:
1583: // os << "Base point " << *b_iter << " with cone:" << std::endl;
1584: // for(typename Sieve<Point_,Color_>::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
1585: // os << " " << *c_iter << std::endl;
1586: // }
1587: // }
1588: // return os;
1589: // };
1590:
1591: //
1592: // The basic Sieve interface
1593: //
1594: template <typename Point_, typename Color_>
1595: void Sieve<Point_, Color_>::clear() {
1596: this->arrows.clear(); this->strata.clear();
1597: };
1599: template <typename Point_, typename Color_>
1600: Obj<typename Sieve<Point_, Color_>::coneSequence> Sieve<Point_, Color_>::cone(const Point_& p) {
1601: return coneSequence(::boost::multi_index::get<targetColor>(this->arrows), p);
1602: }
1603:
1604: template <typename Point_, typename Color_>
1605: template<class InputSequence>
1606: Obj<PointSet> Sieve<Point_, Color_>::cone(const Obj<InputSequence>& points) {
1607: return this->nCone(points, 1);
1608: };
1609:
1610: template <typename Point_, typename Color_>
1611: Obj<typename Sieve<Point_, Color_>::coneSequence> Sieve<Point_, Color_>::cone(const Point_& p, const Color_& color) {
1612: return coneSequence(::boost::multi_index::get<targetColor>(this->arrows), p, color);
1613: };
1614:
1615: template <typename Point_, typename Color_>
1616: template<class InputSequence>
1617: Obj<PointSet> Sieve<Point_, Color_>::cone(const Obj<InputSequence>& points, const Color_& color) {
1618: return this->nCone(points, 1, color);
1619: };
1620:
1621: template <typename Point_, typename Color_>
1622: Obj<PointArray> Sieve<Point_, Color_>::nCone(const Point_& p, int n) {
1623: return this->nCone(p, n, Color_(), false);
1624: };
1625:
1626: template <typename Point_, typename Color_>
1627: Obj<PointArray> Sieve<Point_, Color_>::nCone(const Point_& p, int n, const Color_& color, bool useColor) {
1628: // Obj<PointSet> cone = PointSet();
1629: // cone->insert(p);
1630: // return this->__nCone(cone, n, color, useColor);
1631: Obj<PointArray> cone = PointArray();
1632: Obj<PointSet> seen = PointSet();
1634: this->__nCone(this->cone(p), n-1, color, useColor, cone, seen);
1635: return cone;
1636: };
1638: template <typename Point_, typename Color_>
1639: template<class pointSequence>
1640: void Sieve<Point_, Color_>::__nCone(const Obj<pointSequence>& points, int n, const Color_& color, bool useColor, Obj<PointArray> cone, Obj<PointSet> seen) {
1641: if (n == 0) {
1642: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
1643: if (seen->find(*p_itor) == seen->end()) {
1644: cone->push_back(*p_itor);
1645: seen->insert(*p_itor);
1646: }
1647: }
1648: } else {
1649: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
1650: if (useColor) {
1651: this->__nCone(this->cone(*p_itor, color), n-1, color, useColor, cone, seen);
1652: } else {
1653: this->__nCone(this->cone(*p_itor), n-1, color, useColor, cone, seen);
1654: }
1655: }
1656: }
1657: };
1658:
1659: template <typename Point_, typename Color_>
1660: template<class InputSequence>
1661: Obj<PointSet> Sieve<Point_, Color_>::nCone(const Obj<InputSequence>& points, int n) {
1662: return this->nCone(points, n, Color_(), false);
1663: };
1665: template <typename Point_, typename Color_>
1666: template<class InputSequence>
1667: Obj<PointSet> Sieve<Point_, Color_>::nCone(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
1668: Obj<PointSet> cone = PointSet();
1669: cone->insert(points->begin(), points->end());
1670: return this->__nCone(cone, n, color, useColor);
1671: };
1673: template <typename Point_, typename Color_>
1674: template<class InputSequence>
1675: Obj<PointSet> Sieve<Point_, Color_>::__nCone(Obj<InputSequence>& cone, int n, const Color_& color, bool useColor) {
1676: Obj<PointSet> base = PointSet();
1678: for(int i = 0; i < n; ++i) {
1679: Obj<PointSet> tmp = cone; cone = base; base = tmp;
1680:
1681: cone->clear();
1682: for(PointSet::iterator b_itor = base->begin(); b_itor != base->end(); ++b_itor) {
1683: Obj<coneSequence> pCone;
1684:
1685: if (useColor) {
1686: pCone = this->cone(*b_itor, color);
1687: } else {
1688: pCone = this->cone(*b_itor);
1689: }
1690: cone->insert(pCone->begin(), pCone->end());
1691: }
1692: }
1693: return cone;
1694: };
1696: template <typename Point_, typename Color_>
1697: bool Sieve<Point_, Color_>::coneContains(const Point_& p, const Point_& q) {
1698: //FIX: Shouldn't we just be able to query an arrow?
1699: Obj<coneSequence> cone = this->cone(p);
1700:
1701: for(typename Sieve<Point_, Color_>::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); c_iter++) {
1702: if (*c_iter == q) return true;
1703: }
1704: return false;
1705: }
1707: template <typename Point_, typename Color_>
1708: Obj<typename Sieve<Point_,Color_>::supportSequence> Sieve<Point_, Color_>::support(const Point_& p) {
1709: return supportSequence(::boost::multi_index::get<sourceColor>(this->arrows), p);
1710: };
1712: template <typename Point_, typename Color_>
1713: template<class InputSequence>
1714: Obj<PointSet> Sieve<Point_, Color_>::support(const Obj<InputSequence>& points) {
1715: return this->nSupport(points, 1);
1716: };
1718: template <typename Point_, typename Color_>
1719: Obj<typename Sieve<Point_,Color_>::supportSequence> Sieve<Point_, Color_>::support(const Point_& p, const Color_& color) {
1720: return supportSequence(::boost::multi_index::get<sourceColor>(this->arrows), p, color);
1721: };
1723: template <typename Point_, typename Color_>
1724: template<class InputSequence>
1725: Obj<PointSet> Sieve<Point_, Color_>::support(const Obj<InputSequence>& points, const Color_& color) {
1726: return this->nSupport(points, 1, color);
1727: };
1729: template <typename Point_, typename Color_>
1730: template<class InputSequence>
1731: Obj<PointSet> Sieve<Point_, Color_>::nSupport(const Obj<InputSequence>& points, int n) {
1732: return this->nSupport(points, n, Color_(), false);
1733: };
1735: template <typename Point_, typename Color_>
1736: template<class InputSequence>
1737: Obj<PointSet> Sieve<Point_, Color_>::nSupport(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
1738: Obj<PointSet> support = PointSet();
1739: Obj<PointSet> cap = PointSet();
1740:
1741: support->insert(points->begin(), points->end());
1742: for(int i = 0; i < n; ++i) {
1743: Obj<PointSet> tmp = support; support = cap; cap = tmp;
1744:
1745: support->clear();
1746: for(PointSet::iterator c_itor = cap->begin(); c_itor != cap->end(); ++c_itor) {
1747: Obj<supportSequence> pSupport;
1748:
1749: if (useColor) {
1750: pSupport = this->support(*c_itor, color);
1751: } else {
1752: pSupport = this->support(*c_itor);
1753: }
1754: support->insert(pSupport->begin(), pSupport->end());
1755: }
1756: }
1757: return support;
1758: };
1760: template <typename Point_, typename Color_>
1761: bool Sieve<Point_, Color_>::supportContains(const Point_& q, const Point_& p) {
1762: //FIX: Shouldn't we just be able to query an arrow?
1763: Obj<supportSequence> support = this->support(q);
1764:
1765: for(typename Sieve<Point_, Color_>::supportSequence::iterator s_iter = support->begin(); s_iter != support->end(); s_iter++) {
1766: if (*s_iter == p) return true;
1767: }
1768: return false;
1769: }
1771: //
1772: // Iterated versions
1773: //
1774:
1775: template <typename Point_, typename Color_>
1776: Obj<PointSet> Sieve<Point_,Color_>::closure(const Point_& p) {
1777: return nClosure(p, this->depth());
1778: };
1779:
1780: template <typename Point_, typename Color_>
1781: Obj<PointSet> Sieve<Point_,Color_>::closure(const Point_& p, const Color_& color) {
1782: return nClosure(p, this->depth(), color);
1783: };
1785: template <typename Point_, typename Color_>
1786: template<class InputSequence>
1787: Obj<PointSet> Sieve<Point_,Color_>::closure(const Obj<InputSequence>& points) {
1788: return nClosure(points, this->depth());
1789: };
1790:
1791: template <typename Point_, typename Color_>
1792: template<class InputSequence>
1793: Obj<PointSet> Sieve<Point_,Color_>::closure(const Obj<InputSequence>& points, const Color_& color) {
1794: return nClosure(points, this->depth(), color);
1795: };
1796:
1797: template <typename Point_, typename Color_>
1798: Obj<PointSet> Sieve<Point_,Color_>::nClosure(const Point_& p, int n) {
1799: return this->nClosure(p, n, Color_(), false);
1800: };
1802: template <typename Point_, typename Color_>
1803: Obj<PointSet> Sieve<Point_,Color_>::nClosure(const Point_& p, int n, const Color_& color, bool useColor ) {
1804: Obj<PointSet> cone = PointSet();
1805:
1806: cone->insert(p);
1807: return this->__nClosure(cone, n, color, useColor);
1808: };
1810: template <typename Point_, typename Color_>
1811: template<class InputSequence>
1812: Obj<PointSet> Sieve<Point_,Color_>::nClosure(const Obj<InputSequence>& points, int n) {
1813: return this->nClosure(points, n, Color_(), false);
1814: };
1816: template <typename Point_, typename Color_>
1817: template<class InputSequence>
1818: Obj<PointSet> Sieve<Point_,Color_>::nClosure(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
1819: Obj<PointSet> cone = PointSet();
1820: cone->insert(points->begin(), points->end());
1821: return this->__nClosure(cone, n, color, useColor);
1822: };
1824: template <typename Point_, typename Color_>
1825: template<class InputSequence>
1826: Obj<PointSet> Sieve<Point_,Color_>::__nClosure(Obj<InputSequence>& cone, int n, const Color_& color, bool useColor) {
1827: Obj<PointSet> base = PointSet();
1828: Obj<PointSet> closure = PointSet();
1829:
1830: for(int i = 0; i < n; ++i) {
1831: Obj<PointSet> tmp = cone; cone = base; base = tmp;
1832:
1833: cone->clear();
1834: for(PointSet::iterator b_itor = base->begin(); b_itor != base->end(); ++b_itor) {
1835: Obj<coneSequence> pCone;
1836:
1837: if (useColor) {
1838: pCone = this->cone(*b_itor, color);
1839: } else {
1840: pCone = this->cone(*b_itor);
1841: }
1842: cone->insert(pCone->begin(), pCone->end());
1843: closure->insert(pCone->begin(), pCone->end());
1844: }
1845: }
1846: return closure;
1847: };
1849: template <typename Point_, typename Color_>
1850: Obj<Sieve<Point_,Color_> > Sieve<Point_,Color_>::closureSieve(const Point_& p) {
1851: return nClosureSieve(p, this->depth());
1852: };
1854: template <typename Point_, typename Color_>
1855: Obj<Sieve<Point_,Color_> > Sieve<Point_,Color_>::closureSieve(const Point_& p, const Color_& color) {
1856: return nClosureSieve(p, this->depth(), color);
1857: };
1858:
1859: template <typename Point_, typename Color_>
1860: template<class InputSequence>
1861: Obj<Sieve<Point_,Color_> > Sieve<Point_,Color_>::closureSieve(const Obj<InputSequence>& points) {
1862: return nClosureSieve(points, this->depth());
1863: };
1864:
1865: template <typename Point_, typename Color_>
1866: template<class InputSequence>
1867: Obj<Sieve<Point_,Color_> > Sieve<Point_,Color_>::closureSieve(const Obj<InputSequence>& points, const Color_& color) {
1868: return nClosureSieve(points, this->depth(), color);
1869: };
1870:
1871: template <typename Point_, typename Color_>
1872: Obj<Sieve<Point_,Color_> > Sieve<Point_,Color_>::nClosureSieve(const Point_& p, int n) {
1873: return this->nClosureSieve(p, n, Color_(), false);
1874: };
1875:
1876: template <typename Point_, typename Color_>
1877: Obj<Sieve<Point_,Color_> > Sieve<Point_,Color_>::nClosureSieve(const Point_& p, int n, const Color_& color, bool useColor ) {
1878: Obj<PointSet> cone = PointSet();
1879:
1880: cone->insert(p);
1881: return this->__nClosureSieve(cone, n, color, useColor);
1882: };
1883:
1884: template <typename Point_, typename Color_>
1885: template<class InputSequence>
1886: Obj<Sieve<Point_,Color_> > Sieve<Point_,Color_>::nClosureSieve(const Obj<InputSequence>& points, int n) {
1887: return this->nClosureSieve(points, n, Color_(), false);
1888: };
1889:
1890: template <typename Point_, typename Color_>
1891: template<class InputSequence>
1892: Obj<Sieve<Point_,Color_> > Sieve<Point_,Color_>::nClosureSieve(const Obj<InputSequence>& points, int n,
1893: const Color_& color, bool useColor ) {
1894: Obj<PointSet> cone = PointSet();
1895:
1896: cone->insert(points->begin(), points->end());
1897: return this->__nClosureSieve(cone, n, color, useColor);
1898: };
1899:
1900: template <typename Point_, typename Color_>
1901: template<class InputSequence>
1902: Obj<Sieve<Point_,Color_> > Sieve<Point_,Color_>::__nClosureSieve(Obj<InputSequence>& cone,int n,const Color_& color,bool useColor) {
1903: Obj<PointSet> base = PointSet();
1904: Obj<Sieve<Point_,Color_> > closure = Sieve<Point_,Color_>();
1905:
1906: for(int i = 0; i < n; ++i) {
1907: Obj<PointSet> tmp = cone; cone = base; base = tmp;
1908:
1909: cone->clear();
1910: for(PointSet::iterator b_itor = base->begin(); b_itor != base->end(); ++b_itor) {
1911: Obj<coneSequence> pCone;
1912:
1913: if (useColor) {
1914: pCone = this->cone(*b_itor, color);
1915: } else {
1916: pCone = this->cone(*b_itor);
1917: }
1918: cone->insert(pCone->begin(), pCone->end());
1919: closure->addCone(pCone, *b_itor);
1920: }
1921: }
1922: return closure;
1923: };
1924:
1925: template <typename Point_, typename Color_>
1926: Obj<PointSet> Sieve<Point_,Color_>::star(const Point_& p) {
1927: return nStar(p, this->height());
1928: };
1929:
1930: template <typename Point_, typename Color_>
1931: Obj<PointSet> Sieve<Point_,Color_>::star(const Point_& p, const Color_& color) {
1932: return nStar(p, this->depth(), color);
1933: };
1934:
1935: template <typename Point_, typename Color_>
1936: template<class InputSequence>
1937: Obj<PointSet> Sieve<Point_,Color_>::star(const Obj<InputSequence>& points) {
1938: return nStar(points, this->height());
1939: };
1940:
1941: template <typename Point_, typename Color_>
1942: template<class InputSequence>
1943: Obj<PointSet> Sieve<Point_,Color_>::star(const Obj<InputSequence>& points, const Color_& color) {
1944: return nStar(points, this->height(), color);
1945: };
1947: template <typename Point_, typename Color_>
1948: Obj<PointSet> Sieve<Point_,Color_>::nStar(const Point_& p, int n) {
1949: return this->nStar(p, n, Color_(), false);
1950: };
1951:
1952: template <typename Point_, typename Color_>
1953: Obj<PointSet> Sieve<Point_,Color_>::nStar(const Point_& p, int n, const Color_& color, bool useColor ) {
1954: Obj<PointSet> support = PointSet();
1955:
1956: support->insert(p);
1957: return this->__nStar(support, n, color, useColor);
1958: };
1960: template <typename Point_, typename Color_>
1961: template<class InputSequence>
1962: Obj<PointSet> Sieve<Point_,Color_>::nStar(const Obj<InputSequence>& points, int n) {
1963: return this->nStar(points, n, Color_(), false);
1964: };
1966: template <typename Point_, typename Color_>
1967: template<class InputSequence>
1968: Obj<PointSet> Sieve<Point_,Color_>::nStar(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
1969: Obj<PointSet> support = PointSet();
1970:
1971: support->insert(points->begin(), points->end());
1972: return this->__nStar(cone, n, color, useColor);
1973: };
1974:
1975: template <typename Point_, typename Color_>
1976: template<class InputSequence>
1977: Obj<PointSet> Sieve<Point_,Color_>::__nStar(Obj<InputSequence>& support, int n, const Color_& color, bool useColor) {
1978: Obj<PointSet> cap = PointSet();
1979: Obj<PointSet> star = PointSet();
1980:
1981: for(int i = 0; i < n; ++i) {
1982: Obj<PointSet> tmp = support; support = base; base = tmp;
1983:
1984: support->clear();
1985: for(PointSet::iterator b_itor = base->begin(); b_itor != base->end(); ++b_itor) {
1986: Obj<supportSequence> pSupport;
1987:
1988: if (useColor) {
1989: pSupport = this->support(*b_itor, color);
1990: } else {
1991: pSupport = this->support(*b_itor);
1992: }
1993: support->insert(pSupport->begin(), pSupport->end());
1994: star->insert(pSupport->begin(), pSupport->end());
1995: }
1996: }
1997: return star;
1998: };
1999:
2000: //
2001: // Lattice methods
2002: //
2004: template <typename Point_, typename Color_>
2005: Obj<PointSet> Sieve<Point_,Color_>::meet(const Point_& p, const Point_& q) {
2006: return nMeet(p, q, this->depth());
2007: };
2008:
2009: template <typename Point_, typename Color_>
2010: Obj<PointSet> Sieve<Point_,Color_>::meet(const Point_& p, const Point_& q, const Color_& color) {
2011: return nMeet(p, q, this->depth(), color);
2012: };
2014: template <typename Point_, typename Color_>
2015: template<class InputSequence>
2016: Obj<PointSet> Sieve<Point_,Color_>::meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1) {
2017: return nMeet(chain0, chain1, this->depth());
2018: };
2020: template <typename Point_, typename Color_>
2021: template<class InputSequence>
2022: Obj<PointSet> Sieve<Point_,Color_>::meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color) {
2023: return nMeet(chain0, chain1, this->depth(), color);
2024: };
2026: template <typename Point_, typename Color_>
2027: Obj<PointSet> Sieve<Point_,Color_>::nMeet(const Point_& p, const Point_& q, int n) {
2028: return nMeet(p, q, n, Color_(), false);
2029: };
2031: template <typename Point_, typename Color_>
2032: Obj<PointSet> Sieve<Point_,Color_>::nMeet(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor ) {
2033: Obj<PointSet> chain0 = PointSet();
2034: Obj<PointSet> chain1 = PointSet();
2035:
2036: chain0->insert(p);
2037: chain1->insert(q);
2038: return this->nMeet(chain0, chain1, n, color, useColor);
2039: };
2041: template <typename Point_, typename Color_>
2042: template<class InputSequence>
2043: Obj<PointSet> Sieve<Point_,Color_>::nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n) {
2044: return this->nMeet(chain0, chain1, n, Color_(), false);
2045: };
2046:
2047: template <typename Point_, typename Color_>
2048: template<class InputSequence>
2049: Obj<PointSet> Sieve<Point_,Color_>::nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1,int n,const Color_& color, bool useColor){
2050: // The strategy is to compute the intersection of cones over the chains, remove the intersection
2051: // and use the remaining two parts -- two disjoined components of the symmetric difference of cones -- as the new chains.
2052: // The intersections at each stage are accumulated and their union is the meet.
2053: // The iteration stops after n steps in addition to the meet of the initial chains or sooner if at least one of the chains is empty.
2054: Obj<PointSet> meet = PointSet();
2055: Obj<PointSet> cone;
2056:
2057: if((chain0->size() != 0) && (chain1->size() != 0)) {
2058: for(int i = 0; i <= n; ++i) {
2059: // Compute the intersection of chains and put it in meet at the same time removing it from c and cc
2060: //std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<PointSet>(meet, meet->begin()));
2061: //chain0->erase(meet->begin(), meet->end());
2062: //chain1->erase(meet->begin(), meet->end());
2063: for(typename InputSequence::iterator iter = chain0->begin(); iter != chain0->end(); ++iter) {
2064: if (chain1->find(*iter) != chain1->end()) {
2065: meet->insert(*iter);
2066: chain0->erase(*iter);
2067: chain1->erase(*iter);
2068: }
2069: }
2070: // Replace each of the cones with a cone over it, and check if either is empty; if so, return what's in meet at the moment.
2071: cone = this->cone(chain0);
2072: chain0->insert(cone->begin(), cone->end());
2073: if(chain0->size() == 0) {
2074: break;
2075: }
2076: cone = this->cone(chain1);
2077: chain1->insert(cone->begin(), cone->end());
2078: if(chain1->size() == 0) {
2079: break;
2080: }
2081: }
2082: }
2083: return meet;
2084: };
2085:
2086: template <typename Point_, typename Color_>
2087: Obj<PointSet> Sieve<Point_,Color_>::join(const Point_& p, const Point_& q) {
2088: return this->nJoin(p, q, this->depth());
2089: };
2090:
2091: template <typename Point_, typename Color_>
2092: Obj<PointSet> Sieve<Point_,Color_>::join(const Point_& p, const Point_& q, const Color_& color) {
2093: return this->nJoin(p, q, this->depth(), color);
2094: };
2096: template <typename Point_, typename Color_>
2097: template<class InputSequence>
2098: Obj<PointSet> Sieve<Point_,Color_>::join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1) {
2099: return this->nJoin(chain0, chain1, this->depth());
2100: };
2101:
2102: template <typename Point_, typename Color_>
2103: template<class InputSequence>
2104: Obj<PointSet> Sieve<Point_,Color_>::join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color) {
2105: return this->nJoin(chain0, chain1, this->depth(), color);
2106: };
2107:
2108: template <typename Point_, typename Color_>
2109: Obj<PointSet> Sieve<Point_,Color_>::nJoin(const Point_& p, const Point_& q, int n) {
2110: return this->nJoin(p, q, n, Color_(), false);
2111: };
2112:
2113: template <typename Point_, typename Color_>
2114: Obj<PointSet> Sieve<Point_,Color_>::nJoin(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor) {
2115: Obj<PointSet> chain0 = PointSet();
2116: Obj<PointSet> chain1 = PointSet();
2117:
2118: chain0->insert(p);
2119: chain1->insert(q);
2120: return this->nJoin(chain0, chain1, n, color, useColor);
2121: };
2123: template <typename Point_, typename Color_>
2124: template<class InputSequence>
2125: Obj<PointSet> Sieve<Point_,Color_>::nJoin(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n) {
2126: return this->nJoin(chain0, chain1, n, Color_(), false);
2127: };
2129: template <typename Point_, typename Color_>
2130: template<class InputSequence>
2131: Obj<PointSet> Sieve<Point_,Color_>::nJoin(const Obj<InputSequence>& chain0,const Obj<InputSequence>& chain1,int n,const Color_& color,bool useColor){
2132: // The strategy is to compute the intersection of supports over the chains, remove the intersection
2133: // and use the remaining two parts -- two disjoined components of the symmetric difference of supports -- as the new chains.
2134: // The intersections at each stage are accumulated and their union is the join.
2135: // The iteration stops after n steps in addition to the join of the initial chains or sooner if at least one of the chains is empty.
2136: Obj<PointSet> join = PointSet();
2137: Obj<PointSet> support;
2138:
2139: if((chain0->size() != 0) && (chain1->size() != 0)) {
2140: for(int i = 0; i <= n; ++i) {
2141: // Compute the intersection of chains and put it in meet at the same time removing it from c and cc
2142: //std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<PointSet>(join.obj(), join->begin()));
2143: //chain0->erase(join->begin(), join->end());
2144: //chain1->erase(join->begin(), join->end());
2145: for(typename InputSequence::iterator iter = chain0->begin(); iter != chain0->end(); ++iter) {
2146: if (chain1->find(*iter) != chain1->end()) {
2147: join->insert(*iter);
2148: chain0->erase(*iter);
2149: chain1->erase(*iter);
2150: }
2151: }
2152: // Replace each of the supports with the support over it, and check if either is empty; if so, return what's in join at the moment.
2153: support = this->support(chain0);
2154: chain0->insert(support->begin(), support->end());
2155: if(chain0->size() == 0) {
2156: break;
2157: }
2158: support = this->support(chain1);
2159: chain1->insert(support->begin(), support->end());
2160: if(chain1->size() == 0) {
2161: break;
2162: }
2163: }
2164: }
2165: return join;
2166: };
2167:
2168: //
2169: // Manipulation
2170: //
2171:
2172: template <typename Point_, typename Color_>
2173: void Sieve<Point_,Color_>::addPoint(const Point_& p) {
2174: this->strata(StratumPoint(p));
2175: };
2177: template <typename Point_, typename Color_>
2178: void Sieve<Point_,Color_>::addArrow(const Point_& p, const Point_& q) {
2179: this->addArrow(p, q, Color_());
2180: };
2182: template <typename Point_, typename Color_>
2183: void Sieve<Point_,Color_>::addArrow(const Point_& p, const Point_& q, const Color_& color) {
2184: this->arrows.insert(Arrow_(p, q, color));
2185: if (debug) {std::cout << "Added " << Arrow_(p, q, color);}
2186: };
2188: template <typename Point_, typename Color_>
2189: template<class InputSequence>
2190: void Sieve<Point_,Color_>::addCone(const Obj<InputSequence >& points, const Point_& p) {
2191: this->addCone(points, p, Color_());
2192: };
2194: template <typename Point_, typename Color_>
2195: template<class InputSequence>
2196: void Sieve<Point_,Color_>::addCone(const Obj<InputSequence >& points, const Point_& p, const Color_& color){
2197: if (debug) {std::cout << "Adding a cone " << std::endl;}
2198: for(typename InputSequence::iterator iter = points->begin(); iter != points->end(); ++iter) {
2199: if (debug) {std::cout << "Adding arrow from " << *iter << " to " << p << "(" << color << ")" << std::endl;}
2200: this->addArrow(*iter, p, color);
2201: }
2202: };
2204: template <typename Point_, typename Color_>
2205: template<class InputSequence>
2206: void Sieve<Point_,Color_>::addSupport(const Point_& p, const Obj<InputSequence >& points) {
2207: this->addSupport(p, points, Color_());
2208: };
2210: template <typename Point_, typename Color_>
2211: template<class InputSequence>
2212: void Sieve<Point_,Color_>::addSupport(const Point_& p, const Obj<InputSequence >& points, const Color_& color) {
2213: if (debug) {std::cout << "Adding a support " << std::endl;}
2214: for(typename InputSequence::iterator iter = points->begin(); iter != points->end(); ++iter) {
2215: if (debug) {std::cout << "Adding arrow from " << p << " to " << *iter << std::endl;}
2216: this->addArrow(p, *iter, color);
2217: }
2218: };
2220: template <typename Point_, typename Color_>
2221: void Sieve<Point_,Color_>::add(const Obj<Sieve<Point_,Color_> >& sieve) {
2222: const typename ::boost::multi_index::index<ArrowSet,target>::type& cones = ::boost::multi_index::get<target>(sieve.arrows);
2223:
2224: for(typename ::boost::multi_index::index<ArrowSet,target>::type::iterator iter = cones.begin(); iter != cones.end(); ++iter) {
2225: this->addArrow(*iter);
2226: }
2227: };
2228:
2230: //
2231: // Structural queries
2232: //
2233: template <typename Point_, typename Color_>
2234: int Sieve<Point_,Color_>::depth() {
2235: return this->maxDepth;
2236: };
2238: template <typename Point_, typename Color_>
2239: int Sieve<Point_,Color_>::depth(const Point_& p) {
2240: return ::boost::multi_index::get<point>(this->strata).find(p)->depth;
2241: };
2242:
2243: template <typename Point_, typename Color_>
2244: template<typename InputSequence>
2245: int Sieve<Point_,Color_>::depth(const Obj<InputSequence>& points) {
2246: const typename ::boost::multi_index::index<StratumSet,point>::type& index =
2247: ::boost::multi_index::get<point>(this->strata);
2248: int maxDepth = -1;
2249:
2250: for(typename InputSequence::iterator iter = points->begin(); iter != points->end(); ++iter) {
2251: maxDepth = std::max(maxDepth, index.find(*iter)->depth);
2252: }
2253: return maxDepth;
2254: };
2256: template <typename Point_, typename Color_>
2257: int Sieve<Point_,Color_>::height() {
2258: return this->maxHeight;
2259: };
2260:
2261: template <typename Point_, typename Color_>
2262: int Sieve<Point_,Color_>::height(const Point_& p) {
2263: return ::boost::multi_index::get<point>(this->strata).find(p)->height;
2264: };
2265:
2266: template <typename Point_, typename Color_>
2267: template<typename InputSequence>
2268: int Sieve<Point_,Color_>::height(const Obj<InputSequence>& points) {
2269: const typename ::boost::multi_index::index<StratumSet,point>::type& index = ::boost::multi_index::get<point>(this->strata);
2270: int maxHeight = -1;
2271:
2272: for(typename InputSequence::iterator iter = points->begin(); iter != points->end(); ++iter) {
2273: maxHeight = std::max(maxHeight, index.find(*iter)->height);
2274: }
2275: return maxHeight;
2276: };
2277:
2278: template <typename Point_, typename Color_>
2279: int Sieve<Point_,Color_>::diameter() {
2280: int globalDiameter;
2281: int MPI_Allreduce(&this->graphDiameter, &globalDiameter, 1, MPI_INT, MPI_MAX, this->comm);
2282: CHKMPIERROR(ierr, ERRORMSG("Error in MPI_Allreduce"));
2283: return globalDiameter;
2284: };
2285:
2286: template <typename Point_, typename Color_>
2287: int Sieve<Point_,Color_>::diameter(const Point_& p) {
2288: return this->depth(p) + this->height(p);
2289: };
2290:
2291: template <typename Point_, typename Color_>
2292: Obj<typename Sieve<Point_,Color_>::depthSequence> Sieve<Point_,Color_>::depthStratum(int d) {
2293: return depthSequence(::boost::multi_index::get<depthTag>(this->strata), d);
2294: };
2295:
2296: template <typename Point_, typename Color_>
2297: Obj<typename Sieve<Point_,Color_>::depthMarkerSequence> Sieve<Point_,Color_>::depthStratum(int d, marker_type m) {
2298: return depthMarkerSequence(::boost::multi_index::get<depthMarker>(this->strata), d, m);
2299: };
2301: template <typename Point_, typename Color_>
2302: Obj<typename Sieve<Point_,Color_>::heightSequence> Sieve<Point_,Color_>::heightStratum(int h) {
2303: return heightSequence(::boost::multi_index::get<heightTag>(this->strata), h);
2304: };
2305:
2306: template <typename Point_, typename Color_>
2307: Obj<typename Sieve<Point_,Color_>::heightMarkerSequence> Sieve<Point_,Color_>::heightStratum(int h, marker_type m) {
2308: return heightMarkerSequence(::boost::multi_index::get<depthMarker>(this->strata), h, m);
2309: };
2311: template <typename Point_, typename Color_>
2312: Obj<typename Sieve<Point_,Color_>::markerSequence> Sieve<Point_,Color_>::markerStratum(marker_type m) {
2313: return markerSequence(::boost::multi_index::get<marker>(this->strata), m);
2314: };
2316: template <typename Point_, typename Color_>
2317: void Sieve<Point_,Color_>::setStratification(bool doStratify) {
2318: this->stratification = doStratify;
2319: };
2320:
2321: template <typename Point_, typename Color_>
2322: bool Sieve<Point_,Color_>::getStratification() {
2323: return this->stratification;
2324: };
2325:
2326: //
2327: // Structural manipulation
2328: //
2329:
2330: template <typename Point_, typename Color_>
2331: void Sieve<Point_,Color_>::setMarker(const point_type& p, const marker_type& marker) {
2332: typename ::boost::multi_index::index<StratumSet,point>::type& index = ::boost::multi_index::get<point>(this->strata);
2333: typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = index.find(p);
2334: if (i != index.end()) {
2335: index.modify(i, changeMarker(marker));
2336: }
2337: };
2339: template <typename Point_, typename Color_>
2340: template<class InputSequence>
2341: void Sieve<Point_,Color_>::setMarker(const Obj<InputSequence>& points, const marker_type& marker) {
2342: typename ::boost::multi_index::index<StratumSet,point>::type& index = ::boost::multi_index::get<point>(this->strata);
2343: changeMarker changer(marker);
2344:
2345: for(typename InputSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
2346: typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = index.find(*p_itor);
2347: if (i != index.end()) {
2348: index.modify(i, changer);
2349: }
2350: }
2351: };
2353: // __FUNCT__ used by the logging macros
2356: template <typename Point_, typename Color_>
2357: void Sieve<Point_,Color_>::stratify(bool show) {
2358: ALE_LOG_EVENT_BEGIN;
2359: this->__computeDegrees();
2360: // FIX: We would like to avoid the copy here with cone() and support()
2361: this->__computeClosureHeights(this->cone(this->leaves()));
2362: this->__computeStarDepths(this->support(this->roots()));
2363:
2364: if (debug || show) {
2365: const typename ::boost::multi_index::index<StratumSet,point>::type& points = ::boost::multi_index::get<point>(this->strata);
2366: for(typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = points.begin(); i != points.end(); i++) {
2367: std::cout << *i << std::endl;
2368: }
2369: }
2370: ALE_LOG_EVENT_END;
2371: };
2374: template <typename Point_, typename Color_>
2375: void Sieve<Point_,Color_>::__computeDegrees() {
2376: const typename ::boost::multi_index::index<ArrowSet,target>::type& cones = ::boost::multi_index::get<target>(this->arrows);
2377: const typename ::boost::multi_index::index<ArrowSet,source>::type& supports = ::boost::multi_index::get<source>(this->arrows);
2378: typename ::boost::multi_index::index<StratumSet,point>::type& points = ::boost::multi_index::get<point>(this->strata);
2379:
2380: for(typename ::boost::multi_index::index<ArrowSet,target>::type::iterator c_iter = cones.begin(); c_iter != cones.end();++c_iter){
2381: if (points.find(c_iter->target) != points.end()) {
2382: typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = points.find(c_iter->target);
2383:
2384: points.modify(i, changeIndegree(cones.count(c_iter->target)));
2385: } else {
2386: StratumPoint p;
2387:
2388: p.point = c_iter->target;
2389: p.indegree = cones.count(c_iter->target);
2390: this->strata.insert(p);
2391: }
2392: }
2393:
2394: for(typename ::boost::multi_index::index<ArrowSet,source>::type::iterator s_iter = supports.begin(); s_iter != supports.end(); ++s_iter) {
2395: if (points.find(s_iter->source) != points.end()) {
2396: typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = points.find(s_iter->source);
2397:
2398: points.modify(i, changeOutdegree(supports.count(s_iter->source)));
2399: } else {
2400: StratumPoint p;
2401:
2402: p.point = s_iter->source;
2403: p.outdegree = supports.count(s_iter->source);
2404: this->strata.insert(p);
2405: }
2406: }
2407: };
2409: template <typename Point_, typename Color_>
2410: template<class InputSequence>
2411: void Sieve<Point_,Color_>::__computeClosureHeights(const Obj<InputSequence>& points) {
2412: typename ::boost::multi_index::index<StratumSet,point>::type& index = ::boost::multi_index::get<point>(this->strata);
2413: Obj<PointSet> modifiedPoints = PointSet();
2414:
2415: for(typename InputSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
2416: // Compute the max height of the points in the support of p, and add 1
2417: int h0 = this->height(*p_itor);
2418: int h1 = this->height(this->support(*p_itor)) + 1;
2419: if(h1 != h0) {
2420: typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = index.find(*p_itor);
2421: index.modify(i, changeHeight(h1));
2422: if (h1 > this->maxHeight) this->maxHeight = h1;
2423: modifiedPoints->insert(*p_itor);
2424: }
2425: }
2426: // FIX: We would like to avoid the copy here with cone()
2427: if(modifiedPoints->size() > 0) {
2428: this->__computeClosureHeights(this->cone(modifiedPoints));
2429: }
2430: };
2432:
2433: template <typename Point_, typename Color_>
2434: template<class InputSequence>
2435: void Sieve<Point_,Color_>::__computeStarDepths(const Obj<InputSequence>& points) {
2436: typename ::boost::multi_index::index<StratumSet,point>::type& index = ::boost::multi_index::get<point>(this->strata);
2437: Obj<PointSet> modifiedPoints = PointSet();
2438:
2439: for(typename InputSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
2440: // Compute the max depth of the points in the support of p, and add 1
2441: int d0 = this->depth(*p_itor);
2442: int d1 = this->depth(this->cone(*p_itor)) + 1;
2443: if(d1 != d0) {
2444: index.modify(index.find(*p_itor), changeDepth(d1));
2445: if (d1 > this->maxDepth) this->maxDepth = d1;
2446: modifiedPoints->insert(*p_itor);
2447: }
2448: }
2449: // FIX: We would like to avoid the copy here with cone()
2450: if(modifiedPoints->size() > 0) {
2451: this->__computeStarDepths(this->support(modifiedPoints));
2452: }
2453: };
2457: } // namespace def
2458:
2459: } // namespace ALE
2461: #endif