Actual source code: Sieve.hh
2: #ifndef included_ALE_Sieve_hh
3: #define included_ALE_Sieve_hh
5: #include <boost/multi_index_container.hpp>
6: #include <boost/multi_index/member.hpp>
7: #include <boost/multi_index/ordered_index.hpp>
8: #include <boost/multi_index/composite_key.hpp>
9: #include <iostream>
11: #ifndef included_ALE_Sifter_hh
12: #include <Sifter.hh>
13: #endif
16: namespace ALE {
18: namespace SieveDef {
19: //
20: // Rec & RecContainer definitions.
21: // Rec is intended to denote a graph point record.
22: //
23: template <typename Point_, typename Marker_>
24: struct Rec {
25: typedef Point_ point_type;
26: typedef Marker_ marker_type;
27: template<typename OtherPoint_, typename OtherMarker_ = Marker_>
28: struct rebind {
29: typedef Rec<OtherPoint_, OtherMarker_> type;
30: };
31: point_type point;
32: int degree;
33: int depth;
34: int height;
35: marker_type marker;
36: // Basic interface
37: Rec() : point(point_type()), degree(0), depth(0), height(0), marker(marker_type()) {};
38: Rec(const Rec& r) : point(r.point), degree(r.degree), depth(r.depth), height(r.height), marker(r.marker) {}
39: Rec(const point_type& p) : point(p), degree(0), depth(0), height(0), marker(marker_type()) {};
40: Rec(const point_type& p, const int degree) : point(p), degree(degree), depth(0), height(0), marker(marker_type()) {};
41: Rec(const point_type& p, const int degree, const int depth, const int height, const marker_type marker) : point(p), degree(degree), depth(depth), height(height), marker(marker) {};
42: // Printing
43: friend std::ostream& operator<<(std::ostream& os, const Rec& p) {
44: os << "<" << p.point << ", "<< p.degree << ", "<< p.depth << ", "<< p.height << ", "<< p.marker << ">";
45: return os;
46: };
48: struct degreeAdjuster {
49: degreeAdjuster(int newDegree) : _newDegree(newDegree) {};
50: void operator()(Rec& r) { r.degree = this->_newDegree; }
51: private:
52: int _newDegree;
53: };
54: };// class Rec
56: template <typename Point_, typename Rec_>
57: struct RecContainerTraits {
58: typedef Rec_ rec_type;
59: typedef typename rec_type::marker_type marker_type;
60: // Index tags
61: struct pointTag{};
62: struct degreeTag{};
63: struct markerTag{};
64: struct depthMarkerTag{};
65: struct heightMarkerTag{};
66: // Rec set definition
67: typedef ::boost::multi_index::multi_index_container<
68: rec_type,
69: ::boost::multi_index::indexed_by<
70: ::boost::multi_index::ordered_unique<
71: ::boost::multi_index::tag<pointTag>, BOOST_MULTI_INDEX_MEMBER(rec_type, typename rec_type::point_type, point)
72: >,
73: // ::boost::multi_index::ordered_non_unique<
74: // ::boost::multi_index::tag<degreeTag>, BOOST_MULTI_INDEX_MEMBER(rec_type, int, degree)
75: // >,
76: ::boost::multi_index::ordered_non_unique<
77: ::boost::multi_index::tag<markerTag>, BOOST_MULTI_INDEX_MEMBER(rec_type, marker_type, marker)
78: >,
79: ::boost::multi_index::ordered_non_unique<
80: ::boost::multi_index::tag<depthMarkerTag>,
81: ::boost::multi_index::composite_key<
82: rec_type, BOOST_MULTI_INDEX_MEMBER(rec_type,int,depth), BOOST_MULTI_INDEX_MEMBER(rec_type,marker_type,marker)>
83: >,
84: ::boost::multi_index::ordered_non_unique<
85: ::boost::multi_index::tag<heightMarkerTag>,
86: ::boost::multi_index::composite_key<
87: rec_type, BOOST_MULTI_INDEX_MEMBER(rec_type,int,height), BOOST_MULTI_INDEX_MEMBER(rec_type,marker_type,marker)>
88: >
89: >,
90: ALE_ALLOCATOR<rec_type>
91: > set_type;
92: //
93: // Return types
94: //
96: class PointSequence {
97: public:
98: typedef ALE::SifterDef::IndexSequenceTraits<typename ::boost::multi_index::index<set_type, pointTag>::type,
99: BOOST_MULTI_INDEX_MEMBER(rec_type, typename rec_type::point_type,point)>
100: traits;
101: protected:
102: const typename traits::index_type& _index;
103: public:
104:
105: // Need to extend the inherited iterator to be able to extract the degree
106: class iterator : public traits::iterator {
107: public:
108: iterator(const typename traits::iterator::itor_type& itor) : traits::iterator(itor) {};
109: virtual const int& degree() const {return this->_itor->degree;};
110: virtual const int& marker() const {return this->_itor->marker;};
111: virtual const int& depth() const {return this->_itor->depth;};
112: virtual const int& height() const {return this->_itor->height;};
113: //void setDegree(const int degree) {this->_index.modify(this->_itor, typename traits::rec_type::degreeAdjuster(degree));};
114: };
115:
116: PointSequence(const PointSequence& seq) : _index(seq._index) {};
117: PointSequence(typename traits::index_type& index) : _index(index) {};
118: virtual ~PointSequence(){};
119:
120: virtual bool empty(){return this->_index.empty();};
121:
122: virtual typename traits::index_type::size_type size() {return this->_index.size();};
124: virtual iterator begin() {
125: // Retrieve the beginning iterator of the index
126: return iterator(this->_index.begin());
127: };
128: virtual iterator end() {
129: // Retrieve the ending iterator of the index
130: // Since the elements in this index are ordered by degree, this amounts to the end() of the index.
131: return iterator(this->_index.end());
132: };
133: virtual bool contains(const typename rec_type::point_type& p) {
134: // Check whether a given point is in the index
135: return (this->_index.find(p) != this->_index.end());
136: };
137: }; // class PointSequence
139: template<typename Tag_, typename Value_>
140: class ValueSequence {
141: public:
142: typedef Value_ value_type;
143: typedef ALE::SifterDef::IndexSequenceTraits<typename ::boost::multi_index::index<set_type, Tag_>::type,
144: BOOST_MULTI_INDEX_MEMBER(rec_type, typename rec_type::point_type,point)>
145: traits;
146: protected:
147: const typename traits::index_type& _index;
148: const value_type _value;
149: public:
150: // Need to extend the inherited iterator to be able to extract the degree
151: class iterator : public traits::iterator {
152: public:
153: iterator(const typename traits::iterator::itor_type& itor) : traits::iterator(itor) {};
154: virtual const int& degree() const {return this->_itor->degree;};
155: virtual const int& marker() const {return this->_itor->marker;};
156: virtual const int& depth() const {return this->_itor->depth;};
157: virtual const int& height() const {return this->_itor->height;};
158: };
159:
160: ValueSequence(const PointSequence& seq) : _index(seq._index), _value(seq._value) {};
161: ValueSequence(typename traits::index_type& index, const value_type& value) : _index(index), _value(value) {};
162: virtual ~ValueSequence(){};
163:
164: virtual bool empty(){return this->_index.empty();};
165:
166: virtual typename traits::index_type::size_type size() {return this->_index.count(this->_value);};
168: virtual iterator begin() {
169: return iterator(this->_index.lower_bound(this->_value));
170: };
171: virtual iterator end() {
172: return iterator(this->_index.upper_bound(this->_value));
173: };
174: }; // class ValueSequence
176: template<typename Tag_, typename Value_>
177: class TwoValueSequence {
178: public:
179: typedef Value_ value_type;
180: typedef ALE::SifterDef::IndexSequenceTraits<typename ::boost::multi_index::index<set_type, Tag_>::type,
181: BOOST_MULTI_INDEX_MEMBER(rec_type, typename rec_type::point_type,point)>
182: traits;
183: protected:
184: const typename traits::index_type& _index;
185: const value_type _valueA, _valueB;
186: const bool _useTwoValues;
187: public:
188: // Need to extend the inherited iterator to be able to extract the degree
189: class iterator : public traits::iterator {
190: public:
191: iterator(const typename traits::iterator::itor_type& itor) : traits::iterator(itor) {};
192: virtual const int& degree() const {return this->_itor->degree;};
193: virtual const int& marker() const {return this->_itor->marker;};
194: };
195:
196: TwoValueSequence(const PointSequence& seq) : _index(seq._index), _valueA(seq._valueA), _valueB(seq._valueB), _useTwoValues(seq._useTwoValues) {};
197: TwoValueSequence(typename traits::index_type& index, const value_type& valueA) : _index(index), _valueA(valueA), _valueB(value_type()), _useTwoValues(false) {};
198: TwoValueSequence(typename traits::index_type& index, const value_type& valueA, const value_type& valueB) : _index(index), _valueA(valueA), _valueB(valueB), _useTwoValues(true) {};
199: virtual ~TwoValueSequence(){};
200:
201: virtual bool empty(){return this->_index.empty();};
202:
203: virtual typename traits::index_type::size_type size() {
204: if (this->_useTwoValues) {
205: return this->_index.count(::boost::make_tuple(this->_valueA,this->_valueB));
206: } else {
207: return this->_index.count(::boost::make_tuple(this->_valueA));
208: }
209: };
211: virtual iterator begin() {
212: if (this->_useTwoValues) {
213: return iterator(this->_index.lower_bound(::boost::make_tuple(this->_valueA,this->_valueB)));
214: } else {
215: return iterator(this->_index.lower_bound(::boost::make_tuple(this->_valueA)));
216: }
217: };
218: virtual iterator end() {
219: if (this->_useTwoValues) {
220: return iterator(this->_index.upper_bound(::boost::make_tuple(this->_valueA,this->_valueB)));
221: } else {
222: return iterator(this->_index.upper_bound(::boost::make_tuple(this->_valueA)));
223: }
224: };
225: }; // class TwoValueSequence
226: };// struct RecContainerTraits
228: template <typename Point_, typename Rec_>
229: struct RecContainer {
230: typedef RecContainerTraits<Point_, Rec_> traits;
231: typedef typename traits::set_type set_type;
232: template <typename OtherPoint_, typename OtherRec_>
233: struct rebind {
234: typedef RecContainer<OtherPoint_, OtherRec_> type;
235: };
236: set_type set;
238: void removePoint(const typename traits::rec_type::point_type& p) {
239: typename ::boost::multi_index::index<set_type, typename traits::pointTag>::type& index =
240: ::boost::multi_index::get<typename traits::pointTag>(this->set);
241: typename ::boost::multi_index::index<set_type, typename traits::pointTag>::type::iterator i = index.find(p);
242: if (i != index.end()) { // Point exists
243: index.erase(i);
244: }
245: };
246: void adjustDegree(const typename traits::rec_type::point_type& p, int delta) {
247: typename ::boost::multi_index::index<set_type, typename traits::pointTag>::type& index =
248: ::boost::multi_index::get<typename traits::pointTag>(this->set);
249: typename ::boost::multi_index::index<set_type, typename traits::pointTag>::type::iterator i = index.find(p);
250: if (i == index.end()) { // No such point exists
251: if(delta < 0) { // Cannot decrease degree of a non-existent point
252: ostringstream err;
253: err << "ERROR: adjustDegree: Non-existent point " << p;
254: std::cout << err << std::endl;
255: throw(Exception(err.str().c_str()));
256: }
257: else { // We CAN INCREASE the degree of a non-existent point: simply insert a new element with degree == delta
258: std::pair<typename ::boost::multi_index::index<set_type, typename traits::pointTag>::type::iterator, bool> ii;
259: typename traits::rec_type r(p,delta);
260: ii = index.insert(r);
261: if(ii.second == false) {
262: ostringstream err;
263: err << "ERROR: adjustDegree: Failed to insert a rec " << r;
264: std::cout << err << std::endl;
265: throw(Exception(err.str().c_str()));
266: }
267: }
268: }
269: else { // Point exists, so we try to modify its degree
270: // If the adjustment is zero, there is nothing to do, otherwise ...
271: if(delta != 0) {
272: int newDegree = i->degree + delta;
273: if(newDegree < 0) {
274: ostringstream ss;
275: ss << "adjustDegree: Adjustment of " << *i << " by " << delta << " would result in negative degree: " << newDegree;
276: throw Exception(ss.str().c_str());
277: }
278: index.modify(i, typename traits::rec_type::degreeAdjuster(newDegree));
279: }
280: }
281: }; // adjustDegree()
282: }; // struct RecContainer
283: };// namespace SieveDef
285: //
286: // Sieve:
287: // A Sieve is a set of {\emph arrows} connecting {\emph points} of type Point_. Thus we
288: // could realize a sieve, for instance, as a directed graph. In addition, we will often
289: // assume an acyclicity constraint, arriving at a DAG. Each arrow may also carry a label,
290: // or {\emph color} of type Color_, and the interface allows sets of arrows to be filtered
291: // by color.
292: //
293: template <typename Point_, typename Marker_, typename Color_>
294: class Sieve : public ALE::Sifter<Point_, Point_, Color_, ::boost::multi_index::composite_key_compare<std::less<Point_>, std::less<Color_>, std::less<Point_> >, SieveDef::RecContainer<Point_, SieveDef::Rec<Point_, Marker_> >, SieveDef::RecContainer<Point_, SieveDef::Rec<Point_, Marker_> > > {
295: public:
296: typedef Color_ color_type;
297: typedef Point_ point_type;
298: typedef Marker_ marker_type;
299: typedef struct {
300: typedef ALE::Sifter<Point_, Point_, Color_, ::boost::multi_index::composite_key_compare<std::less<Point_>, std::less<Color_>, std::less<Point_> >, SieveDef::RecContainer<Point_, SieveDef::Rec<Point_, Marker_> >, SieveDef::RecContainer<Point_, SieveDef::Rec<Point_, Marker_> > > baseType;
301: // Encapsulated container types
302: typedef typename baseType::traits::arrow_container_type arrow_container_type;
303: typedef typename baseType::traits::cap_container_type cap_container_type;
304: typedef typename baseType::traits::base_container_type base_container_type;
305: // Types associated with records held in containers
306: typedef typename baseType::traits::arrow_type arrow_type;
307: typedef typename baseType::traits::source_type source_type;
308: typedef typename baseType::traits::sourceRec_type sourceRec_type;
309: typedef typename baseType::traits::target_type target_type;
310: typedef typename baseType::traits::targetRec_type targetRec_type;
311: typedef typename baseType::traits::color_type color_type;
312: typedef Point_ point_type;
313: // Convenient tag names
314: typedef typename baseType::traits::supportInd supportInd;
315: typedef typename baseType::traits::coneInd coneInd;
316: typedef typename baseType::traits::arrowInd arrowInd;
317: typedef typename baseType::traits::baseInd baseInd;
318: typedef typename baseType::traits::capInd capInd;
320: //
321: // Return types
322: //
323: typedef typename baseType::traits::arrowSequence arrowSequence;
324: typedef typename baseType::traits::coneSequence coneSequence;
325: typedef typename baseType::traits::supportSequence supportSequence;
326: typedef typename baseType::traits::baseSequence baseSequence;
327: typedef typename baseType::traits::capSequence capSequence;
328: typedef typename base_container_type::traits::template TwoValueSequence<typename base_container_type::traits::depthMarkerTag,int> depthSequence;
329: typedef typename cap_container_type::traits::template TwoValueSequence<typename cap_container_type::traits::heightMarkerTag,int> heightSequence;
330: typedef typename cap_container_type::traits::template ValueSequence<typename cap_container_type::traits::markerTag,marker_type> markerSequence;
331: } traits;
332: typedef std::set<point_type> pointSet;
333: typedef ALE::array<point_type> pointArray;
334: typedef std::set<marker_type> markerSet;
335: typedef pointSet coneSet;
336: typedef pointSet supportSet;
337: typedef pointArray coneArray;
338: typedef pointArray supportArray;
339: public:
340: Sieve(MPI_Comm comm = PETSC_COMM_SELF, const int& debug = 0) : ALE::Sifter<Point_, Point_, Color_, ::boost::multi_index::composite_key_compare<std::less<Point_>, std::less<Color_>, std::less<Point_> >, SieveDef::RecContainer<Point_, SieveDef::Rec<Point_, Marker_> >, SieveDef::RecContainer<Point_, SieveDef::Rec<Point_, Marker_> > >(comm, debug), doStratify(false), maxDepth(-1), maxHeight(-1), graphDiameter(-1) {
341: this->_markers = new markerSet();
342: this->_meetSet = new coneSet();
343: };
344: virtual ~Sieve() {};
345: // Printing
346: friend std::ostream& operator<<(std::ostream& os, Obj<Sieve<Point_,Marker_,Color_> > s) {
347: os << *s;
348: return os;
349: };
350:
351: friend std::ostream& operator<<(std::ostream& os, Sieve<Point_,Marker_,Color_>& s) {
352: Obj<typename traits::baseSequence> base = s.base();
353: for(typename traits::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
354: Obj<typename traits::coneSequence> cone = s.cone(*b_iter);
355: os << "Base point " << *b_iter << " with cone:" << std::endl;
356: for(typename traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
357: os << " " << *c_iter << std::endl;
358: }
359: }
360: return os;
361: };
363: template<typename ostream_type>
364: void view(ostream_type& os, const char* label, bool rawData);
365: void view(const char* label, MPI_Comm comm);
367: Obj<Sieve> copy() {
368: Obj<Sieve> s = Sieve(this->comm(), this->debug);
369: Obj<typename traits::capSequence> cap = this->cap();
370: Obj<typename traits::baseSequence> base = this->base();
372: for(typename traits::capSequence::iterator c_iter = cap->begin(); c_iter != cap->end(); ++c_iter) {
373: s->addCapPoint(*c_iter);
374: }
375: for(typename traits::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
376: Obj<typename traits::coneSequence> cone = this->cone(*b_iter);
378: for(typename traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
379: s->addArrow(*c_iter, *b_iter, c_iter.color());
380: }
381: }
382: s->stratify();
383: return s;
384: };
385: bool hasPoint(const point_type& point) {
386: if (this->baseContains(point) || this->capContains(point)) return true;
387: return false;
388: };
389: private:
390: template<class InputSequence> Obj<coneSet> __nCone(Obj<InputSequence>& cone, int n, const Color_& color, bool useColor);
391: template<class pointSequence> void __nCone(const Obj<pointSequence>& points, int n, const Color_& color, bool useColor, Obj<coneArray> cone, Obj<coneSet> seen);
392: template<class pointSequence> void __nSupport(const Obj<pointSequence>& points, int n, const Color_& color, bool useColor, Obj<supportArray> cone, Obj<supportSet> seen);
393: public:
394: //
395: // The basic Sieve interface (extensions to Sifter)
396: //
397: Obj<coneArray> nCone(const Point_& p, int n);
398: Obj<coneArray> nCone(const Point_& p, int n, const Color_& color, bool useColor = true);
399: template<class InputSequence> Obj<coneSet> nCone(const Obj<InputSequence>& points, int n);
400: template<class InputSequence> Obj<coneSet> nCone(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
402: Obj<supportArray> nSupport(const Point_& p, int n);
403: Obj<supportArray> nSupport(const Point_& p, int n, const Color_& color, bool useColor = true);
404: template<class InputSequence> Obj<supportSet> nSupport(const Obj<InputSequence>& points, int n);
405: template<class InputSequence> Obj<supportSet> nSupport(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
406: public:
407: virtual bool checkArrow(const typename traits::arrow_type& a) {
408: if ((this->_cap.set.find(a.source) == this->_cap.set.end()) && (this->_base.set.find(a.source) == this->_base.set.end())) return false;
409: if ((this->_cap.set.find(a.target) == this->_cap.set.end()) && (this->_base.set.find(a.target) == this->_base.set.end())) return false;
410: return true;
411: };
412: //
413: // Iterated versions
414: //
415: Obj<supportSet> star(const Point_& p);
417: Obj<supportSet> star(const Point_& p, const Color_& color);
419: template<class InputSequence>
420: Obj<supportSet> star(const Obj<InputSequence>& points);
422: template<class InputSequence>
423: Obj<supportSet> star(const Obj<InputSequence>& points, const Color_& color);
425: Obj<supportSet> nStar(const Point_& p, int n);
427: Obj<supportSet> nStar(const Point_& p, int n, const Color_& color, bool useColor = true);
429: template<class InputSequence>
430: Obj<supportSet> nStar(const Obj<InputSequence>& points, int n);
432: template<class InputSequence>
433: Obj<supportSet> nStar(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
435: private:
436: template<class InputSequence>
437: Obj<supportSet> __nStar(Obj<InputSequence>& support, int n, const Color_& color, bool useColor);
439: public:
440: //
441: // Lattice methods
442: //
443: const Obj<coneSet>& meet(const Point_& p, const Point_& q);
445: const Obj<coneSet>& meet(const Point_& p, const Point_& q, const Color_& color);
447: template<class InputSequence>
448: const Obj<coneSet>& meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1);
450: template<class InputSequence>
451: const Obj<coneSet>& meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color);
453: const Obj<coneSet>& nMeet(const Point_& p, const Point_& q, int n);
455: const Obj<coneSet>& nMeet(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor = true);
457: template<class InputSequence>
458: const Obj<coneSet>& nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n);
460: template<class InputSequence>
461: const Obj<coneSet>& nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n,
462: const Color_& color, bool useColor = true);
464: Obj<supportSet> join(const Point_& p, const Point_& q);
466: Obj<supportSet> join(const Point_& p, const Point_& q, const Color_& color);
468: template<class InputSequence>
469: Obj<supportSet> join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1);
471: template<class InputSequence>
472: Obj<supportSet> join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color);
474: template<class InputSequence>
475: Obj<supportSet> nJoin1(const Obj<InputSequence>& chain);
477: Obj<supportSet> nJoin(const Point_& p, const Point_& q, int n);
479: Obj<supportSet> nJoin(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor = true);
481: template<class InputSequence>
482: Obj<supportSet> nJoin(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n);
484: template<class InputSequence>
485: Obj<supportSet> nJoin(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n, const Color_& color, bool useColor = true);
487: public:
488: Obj<typename traits::depthSequence> roots() {
489: return this->depthStratum(0);
490: };
491: Obj<typename traits::heightSequence> leaves() {
492: return this->heightStratum(0);
493: };
494: private:
495: bool doStratify;
496: int maxDepth, maxHeight, graphDiameter;
497: public:
498: //
499: // Structural queries
500: //
501: int depth();
502: int depth(const point_type& p);
503: template<typename InputSequence> int depth(const Obj<InputSequence>& points);
505: int height();
506: int height(const point_type& p);
507: template<typename InputSequence> int height(const Obj<InputSequence>& points);
509: int diameter();
510: int diameter(const point_type& p);
512: Obj<typename traits::depthSequence> depthStratum(int d);
513: Obj<typename traits::depthSequence> depthStratum(int d, marker_type m);
515: Obj<typename traits::heightSequence> heightStratum(int h);
516: Obj<typename traits::heightSequence> heightStratum(int h, marker_type m);
518: Obj<typename traits::markerSequence> markerStratum(marker_type m);
519:
520: void setStratification(bool doStratify) {this->doStratify = doStratify;};
522: bool getStratification() {return this->doStratify;};
524: void stratify(bool show = false);
525: protected:
526: Obj<markerSet> _markers;
527: Obj<coneSet> _meetSet;
528: public:
529: //
530: // Structural manipulation
531: //
533: struct changeMarker {
534: changeMarker(int newMarker) : newMarker(newMarker) {};
536: void operator()(typename traits::base_container_type::traits::rec_type& p) {
537: p.marker = newMarker;
538: }
539: private:
540: marker_type newMarker;
541: };
543: void setMarker(const point_type& p, const marker_type& marker);
544: template<class InputSequence> void setMarker(const Obj<InputSequence>& points, const marker_type& marker);
546: void clearMarkers() {this->_markers.clear();};
547: Obj<markerSet> markers() {return this->_markers;};
548: private:
549: struct changeHeight {
550: changeHeight(int newHeight) : newHeight(newHeight) {};
552: void operator()(typename traits::base_container_type::traits::rec_type& p) {
553: p.height = newHeight;
554: }
555: private:
556: int newHeight;
557: };
558:
559: template<class InputSequence> void __computeClosureHeights(const Obj<InputSequence>& points);
561: struct changeDepth {
562: changeDepth(int newDepth) : newDepth(newDepth) {};
564: void operator()(typename traits::base_container_type::traits::rec_type& p) {
565: p.depth = newDepth;
566: }
567: private:
568: int newDepth;
569: };
571: template<class InputSequence> void __computeStarDepths(const Obj<InputSequence>& points);
572: };
574: template <typename Point_, typename Marker_, typename Color_>
575: Obj<typename Sieve<Point_,Marker_,Color_>::coneArray> Sieve<Point_,Marker_,Color_>::nCone(const Point_& p, int n) {
576: return this->nCone(p, n, Color_(), false);
577: };
579: template <typename Point_, typename Marker_, typename Color_>
580: Obj<typename Sieve<Point_,Marker_,Color_>::coneArray> Sieve<Point_,Marker_,Color_>::nCone(const Point_& p, int n, const Color_& color, bool useColor) {
581: Obj<coneArray> cone = new coneArray();
582: Obj<coneSet> seen = new coneSet();
584: this->__nCone(this->cone(p), n-1, color, useColor, cone, seen);
585: return cone;
586: };
588: template <typename Point_, typename Marker_, typename Color_>
589: template<class pointSequence>
590: void Sieve<Point_,Marker_,Color_>::__nCone(const Obj<pointSequence>& points, int n, const Color_& color, bool useColor, Obj<coneArray> cone, Obj<coneSet> seen) {
591: if (n == 0) {
592: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
593: if (seen->find(*p_itor) == seen->end()) {
594: cone->push_back(*p_itor);
595: seen->insert(*p_itor);
596: }
597: }
598: } else {
599: typename pointSequence::iterator end = points->end();
600: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != end; ++p_itor) {
601: if (useColor) {
602: this->__nCone(this->cone(*p_itor, color), n-1, color, useColor, cone, seen);
603: } else {
604: this->__nCone(this->cone(*p_itor), n-1, color, useColor, cone, seen);
605: }
606: }
607: }
608: };
610: template <typename Point_, typename Marker_, typename Color_>
611: template<class InputSequence>
612: Obj<typename Sieve<Point_,Marker_,Color_>::coneSet> Sieve<Point_,Marker_,Color_>::nCone(const Obj<InputSequence>& points, int n) {
613: return this->nCone(points, n, Color_(), false);
614: };
616: template <typename Point_, typename Marker_, typename Color_>
617: template<class InputSequence>
618: Obj<typename Sieve<Point_,Marker_,Color_>::coneSet> Sieve<Point_,Marker_,Color_>::nCone(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
619: Obj<coneSet> cone = new coneSet();
620: cone->insert(points->begin(), points->end());
621: return this->__nCone(cone, n, color, useColor);
622: };
624: template <typename Point_, typename Marker_, typename Color_>
625: template<class InputSequence>
626: Obj<typename Sieve<Point_,Marker_,Color_>::coneSet> Sieve<Point_,Marker_,Color_>::__nCone(Obj<InputSequence>& cone, int n, const Color_& color, bool useColor) {
627: Obj<coneSet> base = new coneSet();
629: for(int i = 0; i < n; ++i) {
630: Obj<coneSet> tmp = cone; cone = base; base = tmp;
631:
632: cone->clear();
633: for(typename coneSet::iterator b_itor = base->begin(); b_itor != base->end(); ++b_itor) {
634: Obj<typename traits::coneSequence> pCone;
635:
636: if (useColor) {
637: pCone = this->cone(*b_itor, color);
638: } else {
639: pCone = this->cone(*b_itor);
640: }
641: cone->insert(pCone->begin(), pCone->end());
642: }
643: }
644: return cone;
645: };
647: template <typename Point_, typename Marker_, typename Color_>
648: Obj<typename Sieve<Point_,Marker_,Color_>::supportArray> Sieve<Point_,Marker_,Color_>::nSupport(const Point_& p, int n) {
649: return this->nSupport(p, n, Color_(), false);
650: };
652: template <typename Point_, typename Marker_, typename Color_>
653: Obj<typename Sieve<Point_,Marker_,Color_>::supportArray> Sieve<Point_,Marker_,Color_>::nSupport(const Point_& p, int n, const Color_& color, bool useColor) {
654: Obj<supportArray> cone = new supportArray();
655: Obj<supportSet> seen = new supportSet();
657: this->__nSupport(this->support(p), n-1, color, useColor, cone, seen);
658: return cone;
659: };
661: template <typename Point_, typename Marker_, typename Color_>
662: template<class pointSequence>
663: void Sieve<Point_,Marker_,Color_>::__nSupport(const Obj<pointSequence>& points, int n, const Color_& color, bool useColor, Obj<supportArray> support, Obj<supportSet> seen) {
664: if (n == 0) {
665: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
666: if (seen->find(*p_itor) == seen->end()) {
667: support->push_back(*p_itor);
668: seen->insert(*p_itor);
669: }
670: }
671: } else {
672: typename pointSequence::iterator end = points->end();
673: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != end; ++p_itor) {
674: if (useColor) {
675: this->__nSupport(this->support(*p_itor, color), n-1, color, useColor, support, seen);
676: } else {
677: this->__nSupport(this->support(*p_itor), n-1, color, useColor, support, seen);
678: }
679: }
680: }
681: };
683: template <typename Point_, typename Marker_, typename Color_>
684: template<class InputSequence>
685: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nSupport(const Obj<InputSequence>& points, int n) {
686: return this->nSupport(points, n, Color_(), false);
687: };
689: template <typename Point_, typename Marker_, typename Color_>
690: template<class InputSequence>
691: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nSupport(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
692: Obj<supportSet> support = supportSet();
693: Obj<supportSet> cap = supportSet();
694:
695: support->insert(points->begin(), points->end());
696: for(int i = 0; i < n; ++i) {
697: Obj<supportSet> tmp = support; support = cap; cap = tmp;
698:
699: support->clear();
700: for(typename supportSet::iterator c_itor = cap->begin(); c_itor != cap->end(); ++c_itor) {
701: Obj<typename traits::supportSequence> pSupport;
702:
703: if (useColor) {
704: pSupport = this->support(*c_itor, color);
705: } else {
706: pSupport = this->support(*c_itor);
707: }
708: support->insert(pSupport->begin(), pSupport->end());
709: }
710: }
711: return support;
712: };
713: //
714: // Iterated versions
715: //
716: template <typename Point_, typename Marker_, typename Color_>
717: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::star(const Point_& p) {
718: return nStar(p, this->height());
719: };
720:
721: template <typename Point_, typename Marker_, typename Color_>
722: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::star(const Point_& p, const Color_& color) {
723: return nStar(p, this->depth(), color);
724: };
725:
726: template <typename Point_, typename Marker_, typename Color_>
727: template<class InputSequence>
728: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::star(const Obj<InputSequence>& points) {
729: return nStar(points, this->height());
730: };
731:
732: template <typename Point_, typename Marker_, typename Color_>
733: template<class InputSequence>
734: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::star(const Obj<InputSequence>& points, const Color_& color) {
735: return nStar(points, this->height(), color);
736: };
738: template <typename Point_, typename Marker_, typename Color_>
739: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nStar(const Point_& p, int n) {
740: return this->nStar(p, n, Color_(), false);
741: };
742:
743: template <typename Point_, typename Marker_, typename Color_>
744: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nStar(const Point_& p, int n, const Color_& color, bool useColor ) {
745: Obj<supportSet> support = supportSet();
746: support->insert(p);
747: return this->__nStar(support, n, color, useColor);
748: };
750: template <typename Point_, typename Marker_, typename Color_>
751: template<class InputSequence>
752: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nStar(const Obj<InputSequence>& points, int n) {
753: return this->nStar(points, n, Color_(), false);
754: };
756: template <typename Point_, typename Marker_, typename Color_>
757: template<class InputSequence>
758: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nStar(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
759: Obj<supportSet> support = supportSet();
760: support->insert(points->begin(), points->end());
761: return this->__nStar(support, n, color, useColor);
762: };
763:
764: template <typename Point_, typename Marker_, typename Color_>
765: template<class InputSequence>
766: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::__nStar(Obj<InputSequence>& support, int n, const Color_& color, bool useColor) {
767: Obj<supportSet> cap = supportSet();
768: Obj<supportSet> star = supportSet();
769: star->insert(support->begin(), support->end());
770: for(int i = 0; i < n; ++i) {
771: Obj<supportSet> tmp = support; support = cap; cap = tmp;
772: support->clear();
773: for(typename supportSet::iterator c_itor = cap->begin(); c_itor != cap->end(); ++c_itor) {
774: Obj<typename traits::supportSequence> pSupport;
775: if (useColor) {
776: pSupport = this->support(*c_itor, color);
777: } else {
778: pSupport = this->support(*c_itor);
779: }
780: support->insert(pSupport->begin(), pSupport->end());
781: star->insert(pSupport->begin(), pSupport->end());
782: }
783: }
784: return star;
785: };
787: //
788: // Lattice methods
789: //
791: template <typename Point_, typename Marker_, typename Color_>
792: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::meet(const Point_& p, const Point_& q) {
793: return nMeet(p, q, this->depth());
794: };
795:
796: template <typename Point_, typename Marker_, typename Color_>
797: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::meet(const Point_& p, const Point_& q, const Color_& color) {
798: return nMeet(p, q, this->depth(), color);
799: };
801: template <typename Point_, typename Marker_, typename Color_>
802: template<class InputSequence>
803: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1) {
804: return nMeet(chain0, chain1, this->depth());
805: };
807: template <typename Point_, typename Marker_, typename Color_>
808: template<class InputSequence>
809: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color) {
810: return nMeet(chain0, chain1, this->depth(), color);
811: };
813: template <typename Point_, typename Marker_, typename Color_>
814: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::nMeet(const Point_& p, const Point_& q, int n) {
815: if (n == 1) {
816: std::vector<point_type> vecA, vecB;
817: const Obj<typename traits::coneSequence>& coneA = this->cone(p);
818: const typename traits::coneSequence::iterator beginA = coneA->begin();
819: const typename traits::coneSequence::iterator endA = coneA->end();
820: const Obj<typename traits::coneSequence>& coneB = this->cone(q);
821: const typename traits::coneSequence::iterator beginB = coneB->begin();
822: const typename traits::coneSequence::iterator endB = coneB->end();
824: vecA.insert(vecA.begin(), beginA, endA);
825: std::sort(vecA.begin(), vecA.end());
826: vecB.insert(vecB.begin(), beginB, endB);
827: std::sort(vecB.begin(), vecB.end());
828: this->_meetSet->clear();
829: std::set_intersection(vecA.begin(), vecA.end(), vecB.begin(), vecB.end(), std::insert_iterator<typename Sieve<Point_,Marker_,Color_>::coneSet>(*this->_meetSet, this->_meetSet->begin()));
830: return this->_meetSet;
831: }
832: return nMeet(p, q, n, Color_(), false);
833: };
835: template <typename Point_, typename Marker_, typename Color_>
836: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::nMeet(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor ) {
837: Obj<coneSet> chain0 = new coneSet();
838: Obj<coneSet> chain1 = new coneSet();
839: chain0->insert(p);
840: chain1->insert(q);
841: return this->nMeet(chain0, chain1, n, color, useColor);
842: };
844: template <typename Point_, typename Marker_, typename Color_>
845: template<class InputSequence>
846: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n) {
847: return this->nMeet(chain0, chain1, n, Color_(), false);
848: };
849:
850: template <typename Point_, typename Marker_, typename Color_>
851: template<class InputSequence>
852: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1,int n,const Color_& color, bool useColor){
853: // The strategy is to compute the intersection of cones over the chains, remove the intersection
854: // and use the remaining two parts -- two disjoined components of the symmetric difference of cones -- as the new chains.
855: // The intersections at each stage are accumulated and their union is the meet.
856: // 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.
857: Obj<coneSet> cone;
859: this->_meetSet->clear();
860: if((chain0->size() != 0) && (chain1->size() != 0)) {
861: for(int i = 0; i <= n; ++i) {
862: // Compute the intersection of chains and put it in meet at the same time removing it from c and cc
863: std::set<point_type> intersect;
864: //std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<coneSet>(meet, meet->begin()));
865: std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<std::set<point_type> >(intersect, intersect.begin()));
866: this->_meetSet->insert(intersect.begin(), intersect.end());
867: for(typename std::set<point_type>::iterator i_iter = intersect.begin(); i_iter != intersect.end(); ++i_iter) {
868: chain0->erase(chain0->find(*i_iter));
869: chain1->erase(chain1->find(*i_iter));
870: }
871: // 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.
872: cone = this->cone(chain0);
873: chain0->insert(cone->begin(), cone->end());
874: if(chain0->size() == 0) {
875: break;
876: }
877: cone = this->cone(chain1);
878: chain1->insert(cone->begin(), cone->end());
879: if(chain1->size() == 0) {
880: break;
881: }
882: // If both cones are empty, we should quit
883: }
884: }
885: return this->_meetSet;
886: };
887:
888: template <typename Point_, typename Marker_, typename Color_>
889: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::join(const Point_& p, const Point_& q) {
890: return this->nJoin(p, q, this->depth());
891: };
892:
893: template <typename Point_, typename Marker_, typename Color_>
894: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::join(const Point_& p, const Point_& q, const Color_& color) {
895: return this->nJoin(p, q, this->depth(), color);
896: };
898: template <typename Point_, typename Marker_, typename Color_>
899: template<class InputSequence>
900: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1) {
901: return this->nJoin(chain0, chain1, this->depth());
902: };
903:
904: template <typename Point_, typename Marker_, typename Color_>
905: template<class InputSequence>
906: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color) {
907: return this->nJoin(chain0, chain1, this->depth(), color);
908: };
910: // Warning: I think this can be much more efficient by eliminating copies
911: template <typename Point_, typename Marker_, typename Color_>
912: template<class InputSequence>
913: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nJoin1(const Obj<InputSequence>& chain) {
914: Obj<supportSet> join = new supportSet();
915: std::set<point_type> intersectA;
916: std::set<point_type> intersectB;
917: int p = 0;
919: //std::cout << "Doing nJoin1:" << std::endl;
920: for(typename InputSequence::iterator p_iter = chain->begin(); p_iter != chain->end(); ++p_iter) {
921: //std::cout << " point " << *p_iter << std::endl;
922: const Obj<typename traits::supportSequence>& support = this->support(*p_iter);
924: join->insert(support->begin(), support->end());
925: if (p == 0) {
926: intersectB.insert(support->begin(), support->end());
927: p++;
928: } else {
929: std::set_intersection(intersectA.begin(), intersectA.end(), join->begin(), join->end(), std::insert_iterator<std::set<point_type> >(intersectB, intersectB.begin()));
930: }
931: intersectA.clear();
932: intersectA.insert(intersectB.begin(), intersectB.end());
933: intersectB.clear();
934: join->clear();
935: //std::cout << " intersection:" << std::endl;
936: //for(typename std::set<point_type>::iterator i_iter = intersectA.begin(); i_iter != intersectA.end(); ++i_iter) {
937: // std::cout << " " << *i_iter << std::endl;
938: //}
939: }
940: join->insert(intersectA.begin(), intersectA.end());
941: return join;
942: };
943:
944: template <typename Point_, typename Marker_, typename Color_>
945: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nJoin(const Point_& p, const Point_& q, int n) {
946: return this->nJoin(p, q, n, Color_(), false);
947: };
948:
949: template <typename Point_, typename Marker_, typename Color_>
950: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nJoin(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor) {
951: Obj<supportSet> chain0 = supportSet();
952: Obj<supportSet> chain1 = supportSet();
953: chain0->insert(p);
954: chain1->insert(q);
955: return this->nJoin(chain0, chain1, n, color, useColor);
956: };
958: template <typename Point_, typename Marker_, typename Color_>
959: template<class InputSequence>
960: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nJoin(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n) {
961: return this->nJoin(chain0, chain1, n, Color_(), false);
962: };
964: template <typename Point_, typename Marker_, typename Color_>
965: template<class InputSequence>
966: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nJoin(const Obj<InputSequence>& chain0,const Obj<InputSequence>& chain1,int n,const Color_& color,bool useColor){
967: // The strategy is to compute the intersection of supports over the chains, remove the intersection
968: // and use the remaining two parts -- two disjoined components of the symmetric difference of supports -- as the new chains.
969: // The intersections at each stage are accumulated and their union is the join.
970: // 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.
971: Obj<supportSet> join = supportSet();
972: Obj<supportSet> support;
973: // std::cout << "Computing nJoin" << std::endl;
974: // std::cout << " chain 0:" << std::endl;
975: // for(typename InputSequence::iterator i_iter = chain0->begin(); i_iter != chain0->end(); ++i_iter) {
976: // std::cout << " " << *i_iter << std::endl;
977: // }
978: // std::cout << " chain 1:" << std::endl;
979: // for(typename InputSequence::iterator i_iter = chain1->begin(); i_iter != chain1->end(); ++i_iter) {
980: // std::cout << " " << *i_iter << std::endl;
981: // }
982: if((chain0->size() != 0) && (chain1->size() != 0)) {
983: for(int i = 0; i <= n; ++i) {
984: // std::cout << "Level " << i << std::endl;
985: // Compute the intersection of chains and put it in meet at the same time removing it from c and cc
986: std::set<point_type> intersect;
987: //std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<supportSet>(join.obj(), join->begin()));
988: std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<std::set<point_type> >(intersect, intersect.begin()));
989: join->insert(intersect.begin(), intersect.end());
990: // std::cout << " Join set:" << std::endl;
991: // for(typename supportSet::iterator i_iter = join->begin(); i_iter != join->end(); ++i_iter) {
992: // std::cout << " " << *i_iter << std::endl;
993: // }
994: for(typename std::set<point_type>::iterator i_iter = intersect.begin(); i_iter != intersect.end(); ++i_iter) {
995: chain0->erase(chain0->find(*i_iter));
996: chain1->erase(chain1->find(*i_iter));
997: }
998: // 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.
999: support = this->support(chain0);
1000: chain0->insert(support->begin(), support->end());
1001: if(chain0->size() == 0) {
1002: break;
1003: }
1004: // std::cout << " chain 0:" << std::endl;
1005: // for(typename InputSequence::iterator i_iter = chain0->begin(); i_iter != chain0->end(); ++i_iter) {
1006: // std::cout << " " << *i_iter << std::endl;
1007: // }
1008: support = this->support(chain1);
1009: chain1->insert(support->begin(), support->end());
1010: if(chain1->size() == 0) {
1011: break;
1012: }
1013: // std::cout << " chain 1:" << std::endl;
1014: // for(typename InputSequence::iterator i_iter = chain1->begin(); i_iter != chain1->end(); ++i_iter) {
1015: // std::cout << " " << *i_iter << std::endl;
1016: // }
1017: // If both supports are empty, we should quit
1018: }
1019: }
1020: return join;
1021: };
1023: template <typename Point_, typename Marker_, typename Color_>
1024: template<typename ostream_type>
1025: void Sieve<Point_,Marker_,Color_>::view(ostream_type& os, const char* label = NULL, bool rawData = false){
1026: if(label != NULL) {
1027: os << "Viewing Sieve '" << label << "':" << std::endl;
1028: }
1029: else {
1030: os << "Viewing a Sieve:" << std::endl;
1031: }
1032: if(!rawData) {
1033: os << "cap --> base:" << std::endl;
1034: Obj<typename traits::capSequence> cap = this->cap();
1035: for(typename traits::capSequence::iterator capi = cap->begin(); capi != cap->end(); ++capi) {
1036: Obj<typename traits::supportSequence> supp = this->support(*capi);
1037: for(typename traits::supportSequence::iterator suppi = supp->begin(); suppi != supp->end(); ++suppi) {
1038: os << *capi << "--(" << suppi.color() << ")-->" << *suppi << std::endl;
1039: }
1040: }
1041: os << "base <-- cap:" << std::endl;
1042: Obj<typename traits::baseSequence> base = this->base();
1043: for(typename traits::baseSequence::iterator basei = base->begin(); basei != base->end(); ++basei) {
1044: Obj<typename traits::coneSequence> cone = this->cone(*basei);
1045: for(typename traits::coneSequence::iterator conei = cone->begin(); conei != cone->end(); ++conei) {
1046: os << *basei << "<--(" << conei.color() << ")--" << *conei << std::endl;
1047: }
1048: }
1049: os << "cap --> (outdegree, marker, depth, height):" << std::endl;
1050: for(typename traits::capSequence::iterator capi = cap->begin(); capi != cap->end(); ++capi) {
1051: os << *capi << "-->" << capi.degree() << ", " << capi.marker() << ", " << capi.depth() << ", " << capi.height() << std::endl;
1052: }
1053: os << "base --> (indegree, marker, depth, height):" << std::endl;
1054: for(typename traits::baseSequence::iterator basei = base->begin(); basei != base->end(); ++basei) {
1055: os << *basei << "-->" << basei.degree() << ", " << basei.marker() << ", " << basei.depth() << ", " << basei.height() << std::endl;
1056: }
1057: }
1058: else {
1059: os << "'raw' arrow set:" << std::endl;
1060: for(typename traits::arrow_container_type::set_type::iterator ai = this->_arrows.set.begin(); ai != this->_arrows.set.end(); ai++)
1061: {
1062: typename traits::arrow_type arr = *ai;
1063: os << arr << std::endl;
1064: }
1065: os << "'raw' base set:" << std::endl;
1066: for(typename traits::base_container_type::set_type::iterator bi = this->_base.set.begin(); bi != this->_base.set.end(); bi++)
1067: {
1068: typename traits::base_container_type::traits::rec_type bp = *bi;
1069: os << bp << std::endl;
1070: }
1071: os << "'raw' cap set:" << std::endl;
1072: for(typename traits::cap_container_type::set_type::iterator ci = this->_cap.set.begin(); ci != this->_cap.set.end(); ci++)
1073: {
1074: typename traits::cap_container_type::traits::rec_type cp = *ci;
1075: os << cp << std::endl;
1076: }
1077: }
1078: };
1079: template <typename Point_, typename Marker_, typename Color_>
1080: void Sieve<Point_,Marker_,Color_>::view(const char* label = NULL, MPI_Comm comm = MPI_COMM_NULL) {
1081: ostringstream txt;
1083: if (this->debug()) {
1084: std::cout << "viewing a Sieve, comm = " << this->comm() << ", commRank = " << this->commRank() << std::endl;
1085: }
1086: if(label != NULL) {
1087: if(this->commRank() == 0) {
1088: txt << "viewing Sieve :'" << label << "'" << std::endl;
1089: }
1090: }
1091: else {
1092: if(this->commRank() == 0) {
1093: txt << "viewing a Sieve" << std::endl;
1094: }
1095: }
1096: if(this->commRank() == 0) {
1097: txt << "cap --> base:\n";
1098: }
1099: typename traits::capSequence cap = this->cap();
1100: typename traits::baseSequence base = this->base();
1101: if(cap.empty()) {
1102: txt << "[" << this->commRank() << "]: empty" << std::endl;
1103: }
1104: for(typename traits::capSequence::iterator capi = cap.begin(); capi != cap.end(); capi++) {
1105: const Obj<typename traits::supportSequence>& supp = this->support(*capi);
1106: const typename traits::supportSequence::iterator suppEnd = supp->end();
1108: for(typename traits::supportSequence::iterator suppi = supp->begin(); suppi != suppEnd; suppi++) {
1109: txt << "[" << this->commRank() << "]: " << *capi << "--(" << suppi.color() << ")-->" << *suppi << std::endl;
1110: }
1111: }
1112: PetscSynchronizedPrintf(this->comm(), txt.str().c_str());
1113: PetscSynchronizedFlush(this->comm());
1114: //
1115: ostringstream txt1;
1116: if(this->commRank() == 0) {
1117: txt1 << "base --> cap:\n";
1118: }
1119: if(base.empty()) {
1120: txt1 << "[" << this->commRank() << "]: empty" << std::endl;
1121: }
1122: for(typename traits::baseSequence::iterator basei = base.begin(); basei != base.end(); basei++) {
1123: const Obj<typename traits::coneSequence>& cone = this->cone(*basei);
1124: const typename traits::coneSequence::iterator coneEnd = cone->end();
1126: for(typename traits::coneSequence::iterator conei = cone->begin(); conei != coneEnd; conei++) {
1127: txt1 << "[" << this->commRank() << "]: " << *basei << "<--(" << conei.color() << ")--" << *conei << std::endl;
1128: }
1129: }
1130: //
1131: PetscSynchronizedPrintf(this->comm(), txt1.str().c_str());
1132: PetscSynchronizedFlush(this->comm());
1133: //
1134: ostringstream txt2;
1135: if(this->commRank() == 0) {
1136: txt2 << "cap <point, outdegree, marker, depth, height>:\n";
1137: }
1138: txt2 << "[" << this->commRank() << "]: [";
1139: for(typename traits::capSequence::iterator capi = cap.begin(); capi != cap.end(); capi++) {
1140: txt2 << " <" << *capi << ", " << capi.degree() << ", " << capi.marker() << ", " << capi.depth() << ", " << capi.height() << ">";
1141: }
1142: txt2 << " ]" << std::endl;
1143: //
1144: PetscSynchronizedPrintf(this->comm(), txt2.str().c_str());
1145: PetscSynchronizedFlush(this->comm());
1146: //
1147: ostringstream txt3;
1148: if(this->commRank() == 0) {
1149: txt3 << "base <point, indegree, marker, depth, height>:\n";
1150: }
1151: txt3 << "[" << this->commRank() << "]: [";
1152: for(typename traits::baseSequence::iterator basei = base.begin(); basei != base.end(); basei++) {
1153: txt3 << " <" << *basei << "," << basei.degree() << ", " << basei.marker() << ", " << basei.depth() << ", " << basei.height() << ">";
1154: }
1155: txt3 << " ]" << std::endl;
1156: //
1157: PetscSynchronizedPrintf(this->comm(), txt3.str().c_str());
1158: PetscSynchronizedFlush(this->comm());
1159: };
1160: //
1161: // Structural queries
1162: //
1163: template <typename Point_, typename Marker_, typename Color_>
1164: void Sieve<Point_,Marker_,Color_>::setMarker(const point_type& p, const marker_type& marker) {
1165: typename ::boost::multi_index::index<typename traits::base_container_type::set_type,typename traits::base_container_type::traits::pointTag>::type& bIndex = ::boost::multi_index::get<typename traits::base_container_type::traits::pointTag>(this->_base.set);
1166: typename ::boost::multi_index::index<typename traits::cap_container_type::set_type,typename traits::cap_container_type::traits::pointTag>::type& cIndex = ::boost::multi_index::get<typename traits::cap_container_type::traits::pointTag>(this->_cap.set);
1168: if (bIndex.find(p) != bIndex.end()) {
1169: bIndex.modify(bIndex.find(p), changeMarker(marker));
1170: }
1171: if (cIndex.find(p) != cIndex.end()) {
1172: cIndex.modify(cIndex.find(p), changeMarker(marker));
1173: }
1174: this->_markers->insert(marker);
1175: };
1177: template <typename Point_, typename Marker_, typename Color_>
1178: template <typename Sequence>
1179: void Sieve<Point_,Marker_,Color_>::setMarker(const Obj<Sequence>& points, const marker_type& marker) {
1180: for(typename Sequence::iterator p_iter = points->begin(); p_iter != points->end(); ++p_iter) {
1181: this->setMarker(*p_iter, marker);
1182: }
1183: };
1185: template <typename Point_, typename Marker_, typename Color_>
1186: int Sieve<Point_,Marker_,Color_>::depth() {
1187: return this->maxDepth;
1188: };
1189: template <typename Point_, typename Marker_, typename Color_>
1190: int Sieve<Point_,Marker_,Color_>::depth(const point_type& p) {
1191: const typename ::boost::multi_index::index<typename traits::base_container_type::set_type,typename traits::cap_container_type::traits::pointTag>::type& i = ::boost::multi_index::get<typename traits::base_container_type::traits::pointTag>(this->_base.set);
1192: if (i.find(p) != i.end()) {
1193: return i.find(p)->depth;
1194: }
1195: return 0;
1196: };
1197: template <typename Point_, typename Marker_, typename Color_>
1198: template<typename InputSequence>
1199: int Sieve<Point_,Marker_,Color_>::depth(const Obj<InputSequence>& points) {
1200: const typename ::boost::multi_index::index<typename traits::base_container_type::set_type,typename traits::cap_container_type::traits::pointTag>::type& i = ::boost::multi_index::get<typename traits::base_container_type::traits::pointTag>(this->_base.set);
1201: int maxDepth = 0;
1202:
1203: for(typename InputSequence::iterator iter = points->begin(); iter != points->end(); ++iter) {
1204: if (i.find(*iter) != i.end()) {
1205: maxDepth = std::max(maxDepth, i.find(*iter)->depth);
1206: }
1207: }
1208: return maxDepth;
1209: };
1210: template <typename Point_, typename Marker_, typename Color_>
1211: int Sieve<Point_,Marker_,Color_>::height() {
1212: return this->maxHeight;
1213: };
1214: template <typename Point_, typename Marker_, typename Color_>
1215: int Sieve<Point_,Marker_,Color_>::height(const point_type& p) {
1216: const typename ::boost::multi_index::index<typename traits::cap_container_type::set_type,typename traits::cap_container_type::traits::pointTag>::type& i = ::boost::multi_index::get<typename traits::cap_container_type::traits::pointTag>(this->_cap.set);
1217: if (i.find(p) != i.end()) {
1218: return i.find(p)->height;
1219: }
1220: return 0;
1221: };
1222: template <typename Point_, typename Marker_, typename Color_>
1223: template<typename InputSequence>
1224: int Sieve<Point_,Marker_,Color_>::height(const Obj<InputSequence>& points) {
1225: const typename ::boost::multi_index::index<typename traits::cap_container_type::set_type,typename traits::cap_container_type::traits::pointTag>::type& i = ::boost::multi_index::get<typename traits::cap_container_type::traits::pointTag>(this->_cap.set);
1226: int maxHeight = 0;
1227:
1228: for(typename InputSequence::iterator iter = points->begin(); iter != points->end(); ++iter) {
1229: if (i.find(*iter) != i.end()) {
1230: maxHeight = std::max(maxHeight, i.find(*iter)->height);
1231: }
1232: }
1233: return maxHeight;
1234: };
1236: template <typename Point_, typename Marker_, typename Color_>
1237: int Sieve<Point_,Marker_,Color_>::diameter() {
1238: int globalDiameter;
1239: int MPI_Allreduce(&this->graphDiameter, &globalDiameter, 1, MPI_INT, MPI_MAX, this->comm());
1240: CHKMPIERROR(ierr, ERRORMSG("Error in MPI_Allreduce"));
1241: return globalDiameter;
1242: };
1243: template <typename Point_, typename Marker_, typename Color_>
1244: int Sieve<Point_,Marker_,Color_>::diameter(const point_type& p) {
1245: return this->depth(p) + this->height(p);
1246: };
1248: template <typename Point_, typename Marker_, typename Color_>
1249: Obj<typename Sieve<Point_,Marker_,Color_>::traits::depthSequence> Sieve<Point_,Marker_,Color_>::depthStratum(int d) {
1250: if (d == 0) {
1251: return typename traits::depthSequence(::boost::multi_index::get<typename traits::cap_container_type::traits::depthMarkerTag>(this->_cap.set), d);
1252: } else {
1253: return typename traits::depthSequence(::boost::multi_index::get<typename traits::base_container_type::traits::depthMarkerTag>(this->_base.set), d);
1254: }
1255: };
1256: template <typename Point_, typename Marker_, typename Color_>
1257: Obj<typename Sieve<Point_,Marker_,Color_>::traits::depthSequence> Sieve<Point_,Marker_,Color_>::depthStratum(int d, marker_type m) {
1258: if (d == 0) {
1259: return typename traits::depthSequence(::boost::multi_index::get<typename traits::cap_container_type::traits::depthMarkerTag>(this->_cap.set), d, m);
1260: } else {
1261: return typename traits::depthSequence(::boost::multi_index::get<typename traits::base_container_type::traits::depthMarkerTag>(this->_base.set), d, m);
1262: }
1263: };
1264: template <typename Point_, typename Marker_, typename Color_>
1265: Obj<typename Sieve<Point_,Marker_,Color_>::traits::heightSequence> Sieve<Point_,Marker_,Color_>::heightStratum(int h) {
1266: if (h == 0) {
1267: return typename traits::heightSequence(::boost::multi_index::get<typename traits::base_container_type::traits::heightMarkerTag>(this->_base.set), h);
1268: } else {
1269: return typename traits::heightSequence(::boost::multi_index::get<typename traits::cap_container_type::traits::heightMarkerTag>(this->_cap.set), h);
1270: }
1271: };
1272: template <typename Point_, typename Marker_, typename Color_>
1273: Obj<typename Sieve<Point_,Marker_,Color_>::traits::heightSequence> Sieve<Point_,Marker_,Color_>::heightStratum(int h, marker_type m) {
1274: if (h == 0) {
1275: return typename traits::heightSequence(::boost::multi_index::get<typename traits::base_container_type::traits::heightMarkerTag>(this->_base.set), h, m);
1276: } else {
1277: return typename traits::heightSequence(::boost::multi_index::get<typename traits::cap_container_type::traits::heightMarkerTag>(this->_cap.set), h, m);
1278: }
1279: };
1280: template <typename Point_, typename Marker_, typename Color_>
1281: template<class InputSequence>
1282: void Sieve<Point_,Marker_,Color_>::__computeClosureHeights(const Obj<InputSequence>& points) {
1283: typename ::boost::multi_index::index<typename traits::cap_container_type::set_type,typename traits::cap_container_type::traits::pointTag>::type& index = ::boost::multi_index::get<typename traits::cap_container_type::traits::pointTag>(this->_cap.set);
1284: typename ::boost::multi_index::index<typename traits::base_container_type::set_type,typename traits::base_container_type::traits::pointTag>::type& bIndex = ::boost::multi_index::get<typename traits::base_container_type::traits::pointTag>(this->_base.set);
1285: Obj<coneSet> modifiedPoints = coneSet();
1286:
1287: for(typename InputSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
1288: // Compute the max height of the points in the support of p, and add 1
1289: int h0 = this->height(*p_itor);
1290: int h1 = this->height(this->support(*p_itor)) + 1;
1291: if(h1 != h0) {
1292: typename ::boost::multi_index::index<typename traits::base_container_type::set_type,typename traits::base_container_type::traits::pointTag>::type::iterator bIter = bIndex.find(*p_itor);
1294: index.modify(index.find(*p_itor), changeHeight(h1));
1295: if (bIter != bIndex.end()) {
1296: bIndex.modify(bIter, changeHeight(h1));
1297: }
1298: if (h1 > this->maxHeight) this->maxHeight = h1;
1299: modifiedPoints->insert(*p_itor);
1300: }
1301: }
1302: // FIX: We would like to avoid the copy here with cone()
1303: if(modifiedPoints->size() > 0) {
1304: this->__computeClosureHeights(this->cone(modifiedPoints));
1305: }
1306: };
1307: template <typename Point_, typename Marker_, typename Color_>
1308: template<class InputSequence>
1309: void Sieve<Point_,Marker_,Color_>::__computeStarDepths(const Obj<InputSequence>& points) {
1310: typename ::boost::multi_index::index<typename traits::base_container_type::set_type,typename traits::base_container_type::traits::pointTag>::type& index = ::boost::multi_index::get<typename traits::base_container_type::traits::pointTag>(this->_base.set);
1311: typename ::boost::multi_index::index<typename traits::cap_container_type::set_type,typename traits::cap_container_type::traits::pointTag>::type& cIndex = ::boost::multi_index::get<typename traits::cap_container_type::traits::pointTag>(this->_cap.set);
1312: Obj<supportSet> modifiedPoints = supportSet();
1313: for(typename InputSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
1314: // Compute the max depth of the points in the support of p, and add 1
1315: int d0 = this->depth(*p_itor);
1316: int d1 = this->depth(this->cone(*p_itor)) + 1;
1317: if(d1 != d0) {
1318: typename ::boost::multi_index::index<typename traits::cap_container_type::set_type,typename traits::cap_container_type::traits::pointTag>::type::iterator cIter = cIndex.find(*p_itor);
1320: index.modify(index.find(*p_itor), changeDepth(d1));
1321: if (cIter != cIndex.end()) {
1322: cIndex.modify(cIter, changeDepth(d1));
1323: }
1324: if (d1 > this->maxDepth) this->maxDepth = d1;
1325: modifiedPoints->insert(*p_itor);
1326: }
1327: }
1328: // FIX: We would like to avoid the copy here with cone()
1329: if(modifiedPoints->size() > 0) {
1330: this->__computeStarDepths(this->support(modifiedPoints));
1331: }
1332: };
1335: template <typename Point_, typename Marker_, typename Color_>
1336: void Sieve<Point_,Marker_,Color_>::stratify(bool show) {
1337: ALE_LOG_EVENT_BEGIN;
1338: // FIX: We would like to avoid the copy here with cone() and support()
1339: this->__computeClosureHeights(this->cone(this->leaves()));
1340: this->__computeStarDepths(this->support(this->roots()));
1341:
1342: Obj<typename traits::capSequence> base = this->base();
1344: for(typename traits::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
1345: maxDepth = std::max(maxDepth, b_iter.depth());
1346: //b_iter.setDegree(this->cone(*b_iter)->size());
1347: this->_base.adjustDegree(*b_iter, this->cone(*b_iter)->size());
1348: }
1349: Obj<typename traits::capSequence> cap = this->cap();
1351: for(typename traits::capSequence::iterator c_iter = cap->begin(); c_iter != cap->end(); ++c_iter) {
1352: maxHeight = std::max(maxHeight, c_iter.height());
1353: //c_iter.setDegree(this->support(*c_iter)->size());
1354: this->_cap.adjustDegree(*c_iter, this->support(*c_iter)->size());
1355: }
1356: if (this->debug() || show) {
1357: // const typename ::boost::multi_index::index<StratumSet,point>::type& points = ::boost::multi_index::get<point>(this->strata);
1358: // for(typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = points.begin(); i != points.end(); i++) {
1359: // std::cout << *i << std::endl;
1360: // }
1361: }
1362: ALE_LOG_EVENT_END;
1363: };
1364: //
1365: // Structural manipulation
1366: //
1367:
1368: } // namespace ALE
1370: #endif