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: this->set.erase(p);
246: };
247: void adjustDegree(const typename traits::rec_type::point_type& p, int delta) {
248: typename ::boost::multi_index::index<set_type, typename traits::pointTag>::type& index =
249: ::boost::multi_index::get<typename traits::pointTag>(this->set);
250: typename ::boost::multi_index::index<set_type, typename traits::pointTag>::type::iterator i = index.find(p);
251: if (i == index.end()) { // No such point exists
252: if(delta < 0) { // Cannot decrease degree of a non-existent point
253: ostringstream err;
254: err << "ERROR: adjustDegree: Non-existent point " << p;
255: std::cout << err << std::endl;
256: throw(Exception(err.str().c_str()));
257: }
258: else { // We CAN INCREASE the degree of a non-existent point: simply insert a new element with degree == delta
259: std::pair<typename ::boost::multi_index::index<set_type, typename traits::pointTag>::type::iterator, bool> ii;
260: typename traits::rec_type r(p,delta);
261: ii = index.insert(r);
262: if(ii.second == false) {
263: ostringstream err;
264: err << "ERROR: adjustDegree: Failed to insert a rec " << r;
265: std::cout << err << std::endl;
266: throw(Exception(err.str().c_str()));
267: }
268: }
269: }
270: else { // Point exists, so we try to modify its degree
271: // If the adjustment is zero, there is nothing to do, otherwise ...
272: if(delta != 0) {
273: int newDegree = i->degree + delta;
274: if(newDegree < 0) {
275: ostringstream ss;
276: ss << "adjustDegree: Adjustment of " << *i << " by " << delta << " would result in negative degree: " << newDegree;
277: throw Exception(ss.str().c_str());
278: }
279: index.modify(i, typename traits::rec_type::degreeAdjuster(newDegree));
280: }
281: }
282: }; // adjustDegree()
283: }; // struct RecContainer
284: };// namespace SieveDef
286: //
287: // Sieve:
288: // A Sieve is a set of {\emph arrows} connecting {\emph points} of type Point_. Thus we
289: // could realize a sieve, for instance, as a directed graph. In addition, we will often
290: // assume an acyclicity constraint, arriving at a DAG. Each arrow may also carry a label,
291: // or {\emph color} of type Color_, and the interface allows sets of arrows to be filtered
292: // by color.
293: //
294: template <typename Point_, typename Marker_, typename Color_>
295: 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_> > > {
296: public:
297: typedef Color_ color_type;
298: typedef Point_ point_type;
299: typedef Marker_ marker_type;
300: typedef struct {
301: 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;
302: // Encapsulated container types
303: typedef typename baseType::traits::arrow_container_type arrow_container_type;
304: typedef typename baseType::traits::cap_container_type cap_container_type;
305: typedef typename baseType::traits::base_container_type base_container_type;
306: // Types associated with records held in containers
307: typedef typename baseType::traits::arrow_type arrow_type;
308: typedef typename baseType::traits::source_type source_type;
309: typedef typename baseType::traits::sourceRec_type sourceRec_type;
310: typedef typename baseType::traits::target_type target_type;
311: typedef typename baseType::traits::targetRec_type targetRec_type;
312: typedef typename baseType::traits::color_type color_type;
313: typedef Point_ point_type;
314: // Convenient tag names
315: typedef typename baseType::traits::supportInd supportInd;
316: typedef typename baseType::traits::coneInd coneInd;
317: typedef typename baseType::traits::arrowInd arrowInd;
318: typedef typename baseType::traits::baseInd baseInd;
319: typedef typename baseType::traits::capInd capInd;
321: //
322: // Return types
323: //
324: typedef typename baseType::traits::arrowSequence arrowSequence;
325: typedef typename baseType::traits::coneSequence coneSequence;
326: typedef typename baseType::traits::supportSequence supportSequence;
327: typedef typename baseType::traits::baseSequence baseSequence;
328: typedef typename baseType::traits::capSequence capSequence;
329: typedef typename base_container_type::traits::template TwoValueSequence<typename base_container_type::traits::depthMarkerTag,int> depthSequence;
330: typedef typename cap_container_type::traits::template TwoValueSequence<typename cap_container_type::traits::heightMarkerTag,int> heightSequence;
331: typedef typename cap_container_type::traits::template ValueSequence<typename cap_container_type::traits::markerTag,marker_type> markerSequence;
332: } traits;
333: typedef std::set<point_type> pointSet;
334: typedef ALE::array<point_type> pointArray;
335: typedef std::set<marker_type> markerSet;
336: typedef pointSet coneSet;
337: typedef pointSet supportSet;
338: typedef pointArray coneArray;
339: typedef pointArray supportArray;
340: public:
341: 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) {
342: this->_markers = new markerSet();
343: this->_meetSet = new coneSet();
344: };
345: virtual ~Sieve() {};
346: // Printing
347: friend std::ostream& operator<<(std::ostream& os, Obj<Sieve<Point_,Marker_,Color_> > s) {
348: os << *s;
349: return os;
350: };
351:
352: friend std::ostream& operator<<(std::ostream& os, Sieve<Point_,Marker_,Color_>& s) {
353: Obj<typename traits::baseSequence> base = s.base();
354: for(typename traits::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
355: Obj<typename traits::coneSequence> cone = s.cone(*b_iter);
356: os << "Base point " << *b_iter << " with cone:" << std::endl;
357: for(typename traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
358: os << " " << *c_iter << std::endl;
359: }
360: }
361: return os;
362: };
364: template<typename ostream_type>
365: void view(ostream_type& os, const char* label, bool rawData);
366: void view(const char* label, MPI_Comm comm);
368: Obj<Sieve> copy() {
369: Obj<Sieve> s = Sieve(this->comm(), this->debug);
370: Obj<typename traits::capSequence> cap = this->cap();
371: Obj<typename traits::baseSequence> base = this->base();
373: for(typename traits::capSequence::iterator c_iter = cap->begin(); c_iter != cap->end(); ++c_iter) {
374: s->addCapPoint(*c_iter);
375: }
376: for(typename traits::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
377: Obj<typename traits::coneSequence> cone = this->cone(*b_iter);
379: for(typename traits::coneSequence::iterator c_iter = cone->begin(); c_iter != cone->end(); ++c_iter) {
380: s->addArrow(*c_iter, *b_iter, c_iter.color());
381: }
382: }
383: s->stratify();
384: return s;
385: };
386: bool hasPoint(const point_type& point) {
387: if (this->baseContains(point) || this->capContains(point)) return true;
388: return false;
389: };
390: private:
391: template<class InputSequence> Obj<coneSet> __nCone(Obj<InputSequence>& cone, int n, const Color_& color, bool useColor);
392: template<class pointSequence> void __nCone(const Obj<pointSequence>& points, int n, const Color_& color, bool useColor, Obj<coneArray> cone, Obj<coneSet> seen);
393: template<class pointSequence> void __nSupport(const Obj<pointSequence>& points, int n, const Color_& color, bool useColor, Obj<supportArray> cone, Obj<supportSet> seen);
394: public:
395: //
396: // The basic Sieve interface (extensions to Sifter)
397: //
398: Obj<coneArray> nCone(const Point_& p, int n);
399: Obj<coneArray> nCone(const Point_& p, int n, const Color_& color, bool useColor = true);
400: template<class InputSequence> Obj<coneSet> nCone(const Obj<InputSequence>& points, int n);
401: template<class InputSequence> Obj<coneSet> nCone(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
403: Obj<supportArray> nSupport(const Point_& p, int n);
404: Obj<supportArray> nSupport(const Point_& p, int n, const Color_& color, bool useColor = true);
405: template<class InputSequence> Obj<supportSet> nSupport(const Obj<InputSequence>& points, int n);
406: template<class InputSequence> Obj<supportSet> nSupport(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
407: public:
408: virtual bool checkArrow(const typename traits::arrow_type& a) {
409: if ((this->_cap.set.find(a.source) == this->_cap.set.end()) && (this->_base.set.find(a.source) == this->_base.set.end())) return false;
410: if ((this->_cap.set.find(a.target) == this->_cap.set.end()) && (this->_base.set.find(a.target) == this->_base.set.end())) return false;
411: return true;
412: };
413: //
414: // Iterated versions
415: //
416: Obj<supportSet> star(const Point_& p);
418: Obj<supportSet> star(const Point_& p, const Color_& color);
420: template<class InputSequence>
421: Obj<supportSet> star(const Obj<InputSequence>& points);
423: template<class InputSequence>
424: Obj<supportSet> star(const Obj<InputSequence>& points, const Color_& color);
426: Obj<supportSet> nStar(const Point_& p, int n);
428: Obj<supportSet> nStar(const Point_& p, int n, const Color_& color, bool useColor = true);
430: template<class InputSequence>
431: Obj<supportSet> nStar(const Obj<InputSequence>& points, int n);
433: template<class InputSequence>
434: Obj<supportSet> nStar(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor = true);
436: private:
437: template<class InputSequence>
438: Obj<supportSet> __nStar(Obj<InputSequence>& support, int n, const Color_& color, bool useColor);
440: public:
441: //
442: // Lattice methods
443: //
444: const Obj<coneSet>& meet(const Point_& p, const Point_& q);
446: const Obj<coneSet>& meet(const Point_& p, const Point_& q, const Color_& color);
448: template<class InputSequence>
449: const Obj<coneSet>& meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1);
451: template<class InputSequence>
452: const Obj<coneSet>& meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color);
454: const Obj<coneSet>& nMeet(const Point_& p, const Point_& q, int n);
456: const Obj<coneSet>& nMeet(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor = true);
458: template<class InputSequence>
459: const Obj<coneSet>& nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n);
461: template<class InputSequence>
462: const Obj<coneSet>& nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n,
463: const Color_& color, bool useColor = true);
465: Obj<supportSet> join(const Point_& p, const Point_& q);
467: Obj<supportSet> join(const Point_& p, const Point_& q, const Color_& color);
469: template<class InputSequence>
470: Obj<supportSet> join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1);
472: template<class InputSequence>
473: Obj<supportSet> join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color);
475: template<class InputSequence>
476: Obj<supportSet> nJoin1(const Obj<InputSequence>& chain);
478: Obj<supportSet> nJoin(const Point_& p, const Point_& q, int n);
480: Obj<supportSet> nJoin(const Point_& p, const Point_& q, int n, const Color_& color, bool useColor = true);
482: template<class InputSequence>
483: Obj<supportSet> nJoin(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n);
485: template<class InputSequence>
486: Obj<supportSet> nJoin(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n, const Color_& color, bool useColor = true);
488: template<class InputSequence>
489: Obj<supportSet> nJoin(const Obj<InputSequence>& chain, const int depth);
491: public:
492: Obj<typename traits::depthSequence> roots() {
493: return this->depthStratum(0);
494: };
495: Obj<typename traits::heightSequence> leaves() {
496: return this->heightStratum(0);
497: };
498: private:
499: bool doStratify;
500: int maxDepth, maxHeight, graphDiameter;
501: public:
502: //
503: // Structural queries
504: //
505: int depth();
506: int depth(const point_type& p);
507: template<typename InputSequence> int depth(const Obj<InputSequence>& points);
509: int height();
510: int height(const point_type& p);
511: template<typename InputSequence> int height(const Obj<InputSequence>& points);
513: int diameter();
514: int diameter(const point_type& p);
516: Obj<typename traits::depthSequence> depthStratum(int d);
517: Obj<typename traits::depthSequence> depthStratum(int d, marker_type m);
519: Obj<typename traits::heightSequence> heightStratum(int h);
520: Obj<typename traits::heightSequence> heightStratum(int h, marker_type m);
522: Obj<typename traits::markerSequence> markerStratum(marker_type m);
523:
524: void setStratification(bool doStratify) {this->doStratify = doStratify;};
526: bool getStratification() {return this->doStratify;};
528: void stratify(bool show = false);
529: protected:
530: Obj<markerSet> _markers;
531: Obj<coneSet> _meetSet;
532: public:
533: //
534: // Structural manipulation
535: //
537: struct changeMarker {
538: changeMarker(int newMarker) : newMarker(newMarker) {};
540: void operator()(typename traits::base_container_type::traits::rec_type& p) {
541: p.marker = newMarker;
542: }
543: private:
544: marker_type newMarker;
545: };
547: void setMarker(const point_type& p, const marker_type& marker);
548: template<class InputSequence> void setMarker(const Obj<InputSequence>& points, const marker_type& marker);
550: void clearMarkers() {this->_markers.clear();};
551: Obj<markerSet> markers() {return this->_markers;};
552: private:
553: struct changeHeight {
554: changeHeight(int newHeight) : newHeight(newHeight) {};
556: void operator()(typename traits::base_container_type::traits::rec_type& p) {
557: p.height = newHeight;
558: }
559: private:
560: int newHeight;
561: };
562:
563: template<class InputSequence> void __computeClosureHeights(const Obj<InputSequence>& points);
565: struct changeDepth {
566: changeDepth(int newDepth) : newDepth(newDepth) {};
568: void operator()(typename traits::base_container_type::traits::rec_type& p) {
569: p.depth = newDepth;
570: }
571: private:
572: int newDepth;
573: };
575: template<class InputSequence> void __computeStarDepths(const Obj<InputSequence>& points);
576: };
578: template <typename Point_, typename Marker_, typename Color_>
579: Obj<typename Sieve<Point_,Marker_,Color_>::coneArray> Sieve<Point_,Marker_,Color_>::nCone(const Point_& p, int n) {
580: return this->nCone(p, n, Color_(), false);
581: };
583: template <typename Point_, typename Marker_, typename Color_>
584: Obj<typename Sieve<Point_,Marker_,Color_>::coneArray> Sieve<Point_,Marker_,Color_>::nCone(const Point_& p, int n, const Color_& color, bool useColor) {
585: Obj<coneArray> cone = new coneArray();
586: Obj<coneSet> seen = new coneSet();
588: this->__nCone(this->cone(p), n-1, color, useColor, cone, seen);
589: return cone;
590: };
592: template <typename Point_, typename Marker_, typename Color_>
593: template<class pointSequence>
594: void Sieve<Point_,Marker_,Color_>::__nCone(const Obj<pointSequence>& points, int n, const Color_& color, bool useColor, Obj<coneArray> cone, Obj<coneSet> seen) {
595: if (n == 0) {
596: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
597: if (seen->find(*p_itor) == seen->end()) {
598: cone->push_back(*p_itor);
599: seen->insert(*p_itor);
600: }
601: }
602: } else {
603: typename pointSequence::iterator end = points->end();
604: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != end; ++p_itor) {
605: if (useColor) {
606: this->__nCone(this->cone(*p_itor, color), n-1, color, useColor, cone, seen);
607: } else {
608: this->__nCone(this->cone(*p_itor), n-1, color, useColor, cone, seen);
609: }
610: }
611: }
612: };
614: template <typename Point_, typename Marker_, typename Color_>
615: template<class InputSequence>
616: Obj<typename Sieve<Point_,Marker_,Color_>::coneSet> Sieve<Point_,Marker_,Color_>::nCone(const Obj<InputSequence>& points, int n) {
617: return this->nCone(points, n, Color_(), false);
618: };
620: template <typename Point_, typename Marker_, typename Color_>
621: template<class InputSequence>
622: Obj<typename Sieve<Point_,Marker_,Color_>::coneSet> Sieve<Point_,Marker_,Color_>::nCone(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
623: Obj<coneSet> cone = new coneSet();
624: cone->insert(points->begin(), points->end());
625: return this->__nCone(cone, n, color, useColor);
626: };
628: template <typename Point_, typename Marker_, typename Color_>
629: template<class InputSequence>
630: Obj<typename Sieve<Point_,Marker_,Color_>::coneSet> Sieve<Point_,Marker_,Color_>::__nCone(Obj<InputSequence>& cone, int n, const Color_& color, bool useColor) {
631: Obj<coneSet> base = new coneSet();
633: for(int i = 0; i < n; ++i) {
634: Obj<coneSet> tmp = cone; cone = base; base = tmp;
635:
636: cone->clear();
637: for(typename coneSet::iterator b_itor = base->begin(); b_itor != base->end(); ++b_itor) {
638: Obj<typename traits::coneSequence> pCone;
639:
640: if (useColor) {
641: pCone = this->cone(*b_itor, color);
642: } else {
643: pCone = this->cone(*b_itor);
644: }
645: cone->insert(pCone->begin(), pCone->end());
646: }
647: }
648: return cone;
649: };
651: template <typename Point_, typename Marker_, typename Color_>
652: Obj<typename Sieve<Point_,Marker_,Color_>::supportArray> Sieve<Point_,Marker_,Color_>::nSupport(const Point_& p, int n) {
653: return this->nSupport(p, n, Color_(), false);
654: };
656: template <typename Point_, typename Marker_, typename Color_>
657: Obj<typename Sieve<Point_,Marker_,Color_>::supportArray> Sieve<Point_,Marker_,Color_>::nSupport(const Point_& p, int n, const Color_& color, bool useColor) {
658: Obj<supportArray> cone = new supportArray();
659: Obj<supportSet> seen = new supportSet();
661: this->__nSupport(this->support(p), n-1, color, useColor, cone, seen);
662: return cone;
663: };
665: template <typename Point_, typename Marker_, typename Color_>
666: template<class pointSequence>
667: void Sieve<Point_,Marker_,Color_>::__nSupport(const Obj<pointSequence>& points, int n, const Color_& color, bool useColor, Obj<supportArray> support, Obj<supportSet> seen) {
668: if (n == 0) {
669: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
670: if (seen->find(*p_itor) == seen->end()) {
671: support->push_back(*p_itor);
672: seen->insert(*p_itor);
673: }
674: }
675: } else {
676: typename pointSequence::iterator end = points->end();
677: for(typename pointSequence::iterator p_itor = points->begin(); p_itor != end; ++p_itor) {
678: if (useColor) {
679: this->__nSupport(this->support(*p_itor, color), n-1, color, useColor, support, seen);
680: } else {
681: this->__nSupport(this->support(*p_itor), n-1, color, useColor, support, seen);
682: }
683: }
684: }
685: };
687: template <typename Point_, typename Marker_, typename Color_>
688: template<class InputSequence>
689: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nSupport(const Obj<InputSequence>& points, int n) {
690: return this->nSupport(points, n, Color_(), false);
691: };
693: template <typename Point_, typename Marker_, typename Color_>
694: template<class InputSequence>
695: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nSupport(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
696: Obj<supportSet> support = supportSet();
697: Obj<supportSet> cap = supportSet();
698:
699: support->insert(points->begin(), points->end());
700: for(int i = 0; i < n; ++i) {
701: Obj<supportSet> tmp = support; support = cap; cap = tmp;
702:
703: support->clear();
704: for(typename supportSet::iterator c_itor = cap->begin(); c_itor != cap->end(); ++c_itor) {
705: Obj<typename traits::supportSequence> pSupport;
706:
707: if (useColor) {
708: pSupport = this->support(*c_itor, color);
709: } else {
710: pSupport = this->support(*c_itor);
711: }
712: support->insert(pSupport->begin(), pSupport->end());
713: }
714: }
715: return support;
716: };
717: //
718: // Iterated versions
719: //
720: template <typename Point_, typename Marker_, typename Color_>
721: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::star(const Point_& p) {
722: return nStar(p, this->height());
723: };
724:
725: template <typename Point_, typename Marker_, typename Color_>
726: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::star(const Point_& p, const Color_& color) {
727: return nStar(p, this->depth(), color);
728: };
729:
730: template <typename Point_, typename Marker_, typename Color_>
731: template<class InputSequence>
732: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::star(const Obj<InputSequence>& points) {
733: return nStar(points, this->height());
734: };
735:
736: template <typename Point_, typename Marker_, typename Color_>
737: template<class InputSequence>
738: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::star(const Obj<InputSequence>& points, const Color_& color) {
739: return nStar(points, this->height(), color);
740: };
742: template <typename Point_, typename Marker_, typename Color_>
743: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nStar(const Point_& p, int n) {
744: return this->nStar(p, n, Color_(), false);
745: };
746:
747: template <typename Point_, typename Marker_, typename Color_>
748: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nStar(const Point_& p, int n, const Color_& color, bool useColor ) {
749: Obj<supportSet> support = supportSet();
750: support->insert(p);
751: return this->__nStar(support, n, color, useColor);
752: };
754: template <typename Point_, typename Marker_, typename Color_>
755: template<class InputSequence>
756: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nStar(const Obj<InputSequence>& points, int n) {
757: return this->nStar(points, n, Color_(), false);
758: };
760: template <typename Point_, typename Marker_, typename Color_>
761: template<class InputSequence>
762: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nStar(const Obj<InputSequence>& points, int n, const Color_& color, bool useColor ) {
763: Obj<supportSet> support = supportSet();
764: support->insert(points->begin(), points->end());
765: return this->__nStar(support, n, color, useColor);
766: };
767:
768: template <typename Point_, typename Marker_, typename Color_>
769: template<class InputSequence>
770: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::__nStar(Obj<InputSequence>& support, int n, const Color_& color, bool useColor) {
771: Obj<supportSet> cap = supportSet();
772: Obj<supportSet> star = supportSet();
773: star->insert(support->begin(), support->end());
774: for(int i = 0; i < n; ++i) {
775: Obj<supportSet> tmp = support; support = cap; cap = tmp;
776: support->clear();
777: for(typename supportSet::iterator c_itor = cap->begin(); c_itor != cap->end(); ++c_itor) {
778: Obj<typename traits::supportSequence> pSupport;
779: if (useColor) {
780: pSupport = this->support(*c_itor, color);
781: } else {
782: pSupport = this->support(*c_itor);
783: }
784: support->insert(pSupport->begin(), pSupport->end());
785: star->insert(pSupport->begin(), pSupport->end());
786: }
787: }
788: return star;
789: };
791: //
792: // Lattice methods
793: //
795: template <typename Point_, typename Marker_, typename Color_>
796: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::meet(const Point_& p, const Point_& q) {
797: return nMeet(p, q, this->depth());
798: };
799:
800: template <typename Point_, typename Marker_, typename Color_>
801: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::meet(const Point_& p, const Point_& q, const Color_& color) {
802: return nMeet(p, q, this->depth(), color);
803: };
805: template <typename Point_, typename Marker_, typename Color_>
806: template<class InputSequence>
807: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1) {
808: return nMeet(chain0, chain1, this->depth());
809: };
811: template <typename Point_, typename Marker_, typename Color_>
812: template<class InputSequence>
813: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::meet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color) {
814: return nMeet(chain0, chain1, this->depth(), color);
815: };
817: template <typename Point_, typename Marker_, typename Color_>
818: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::nMeet(const Point_& p, const Point_& q, int n) {
819: if (n == 1) {
820: std::vector<point_type> vecA, vecB;
821: const Obj<typename traits::coneSequence>& coneA = this->cone(p);
822: const typename traits::coneSequence::iterator beginA = coneA->begin();
823: const typename traits::coneSequence::iterator endA = coneA->end();
824: const Obj<typename traits::coneSequence>& coneB = this->cone(q);
825: const typename traits::coneSequence::iterator beginB = coneB->begin();
826: const typename traits::coneSequence::iterator endB = coneB->end();
828: vecA.insert(vecA.begin(), beginA, endA);
829: std::sort(vecA.begin(), vecA.end());
830: vecB.insert(vecB.begin(), beginB, endB);
831: std::sort(vecB.begin(), vecB.end());
832: this->_meetSet->clear();
833: 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()));
834: return this->_meetSet;
835: }
836: return nMeet(p, q, n, Color_(), false);
837: };
839: template <typename Point_, typename Marker_, typename Color_>
840: 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 ) {
841: Obj<coneSet> chain0 = new coneSet();
842: Obj<coneSet> chain1 = new coneSet();
843: chain0->insert(p);
844: chain1->insert(q);
845: return this->nMeet(chain0, chain1, n, color, useColor);
846: };
848: template <typename Point_, typename Marker_, typename Color_>
849: template<class InputSequence>
850: const Obj<typename Sieve<Point_,Marker_,Color_>::coneSet>& Sieve<Point_,Marker_,Color_>::nMeet(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n) {
851: return this->nMeet(chain0, chain1, n, Color_(), false);
852: };
853:
854: template <typename Point_, typename Marker_, typename Color_>
855: template<class InputSequence>
856: 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){
857: // The strategy is to compute the intersection of cones over the chains, remove the intersection
858: // and use the remaining two parts -- two disjoined components of the symmetric difference of cones -- as the new chains.
859: // The intersections at each stage are accumulated and their union is the meet.
860: // 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.
861: Obj<coneSet> cone;
863: this->_meetSet->clear();
864: if((chain0->size() != 0) && (chain1->size() != 0)) {
865: for(int i = 0; i <= n; ++i) {
866: // Compute the intersection of chains and put it in meet at the same time removing it from c and cc
867: std::set<point_type> intersect;
868: //std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<coneSet>(meet, meet->begin()));
869: std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<std::set<point_type> >(intersect, intersect.begin()));
870: this->_meetSet->insert(intersect.begin(), intersect.end());
871: for(typename std::set<point_type>::iterator i_iter = intersect.begin(); i_iter != intersect.end(); ++i_iter) {
872: chain0->erase(chain0->find(*i_iter));
873: chain1->erase(chain1->find(*i_iter));
874: }
875: // 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.
876: cone = this->cone(chain0);
877: chain0->insert(cone->begin(), cone->end());
878: if(chain0->size() == 0) {
879: break;
880: }
881: cone = this->cone(chain1);
882: chain1->insert(cone->begin(), cone->end());
883: if(chain1->size() == 0) {
884: break;
885: }
886: // If both cones are empty, we should quit
887: }
888: }
889: return this->_meetSet;
890: };
891:
892: template <typename Point_, typename Marker_, typename Color_>
893: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::join(const Point_& p, const Point_& q) {
894: return this->nJoin(p, q, this->depth());
895: };
896:
897: template <typename Point_, typename Marker_, typename Color_>
898: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::join(const Point_& p, const Point_& q, const Color_& color) {
899: return this->nJoin(p, q, this->depth(), color);
900: };
902: template <typename Point_, typename Marker_, typename Color_>
903: template<class InputSequence>
904: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1) {
905: return this->nJoin(chain0, chain1, this->depth());
906: };
907:
908: template <typename Point_, typename Marker_, typename Color_>
909: template<class InputSequence>
910: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::join(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, const Color_& color) {
911: return this->nJoin(chain0, chain1, this->depth(), color);
912: };
914: // Warning: I think this can be much more efficient by eliminating copies
915: template <typename Point_, typename Marker_, typename Color_>
916: template<class InputSequence>
917: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nJoin1(const Obj<InputSequence>& chain) {
918: Obj<supportSet> join = new supportSet();
919: std::set<point_type> intersectA;
920: std::set<point_type> intersectB;
921: int p = 0;
923: //std::cout << "Doing nJoin1:" << std::endl;
924: for(typename InputSequence::iterator p_iter = chain->begin(); p_iter != chain->end(); ++p_iter) {
925: //std::cout << " point " << *p_iter << std::endl;
926: const Obj<typename traits::supportSequence>& support = this->support(*p_iter);
928: join->insert(support->begin(), support->end());
929: if (p == 0) {
930: intersectB.insert(support->begin(), support->end());
931: p++;
932: } else {
933: std::set_intersection(intersectA.begin(), intersectA.end(), join->begin(), join->end(), std::insert_iterator<std::set<point_type> >(intersectB, intersectB.begin()));
934: }
935: intersectA.clear();
936: intersectA.insert(intersectB.begin(), intersectB.end());
937: intersectB.clear();
938: join->clear();
939: //std::cout << " intersection:" << std::endl;
940: //for(typename std::set<point_type>::iterator i_iter = intersectA.begin(); i_iter != intersectA.end(); ++i_iter) {
941: // std::cout << " " << *i_iter << std::endl;
942: //}
943: }
944: join->insert(intersectA.begin(), intersectA.end());
945: return join;
946: };
948: // Warning: I think this can be much more efficient by eliminating copies
949: template <typename Point_, typename Marker_, typename Color_>
950: template<class InputSequence>
951: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nJoin(const Obj<InputSequence>& chain, const int depth) {
952: Obj<supportSet> join = new supportSet();
953: std::set<point_type> intersectA;
954: std::set<point_type> intersectB;
955: int p = 0;
957: //std::cout << "Doing nJoin1:" << std::endl;
958: for(typename InputSequence::iterator p_iter = chain->begin(); p_iter != chain->end(); ++p_iter) {
959: //std::cout << " point " << *p_iter << std::endl;
960: const Obj<supportArray> support = this->nSupport(*p_iter, depth);
962: join->insert(support->begin(), support->end());
963: if (p == 0) {
964: intersectB.insert(support->begin(), support->end());
965: p++;
966: } else {
967: std::set_intersection(intersectA.begin(), intersectA.end(), join->begin(), join->end(), std::insert_iterator<std::set<point_type> >(intersectB, intersectB.begin()));
968: }
969: intersectA.clear();
970: intersectA.insert(intersectB.begin(), intersectB.end());
971: intersectB.clear();
972: join->clear();
973: //std::cout << " intersection:" << std::endl;
974: //for(typename std::set<point_type>::iterator i_iter = intersectA.begin(); i_iter != intersectA.end(); ++i_iter) {
975: // std::cout << " " << *i_iter << std::endl;
976: //}
977: }
978: join->insert(intersectA.begin(), intersectA.end());
979: return join;
980: };
981:
982: template <typename Point_, typename Marker_, typename Color_>
983: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nJoin(const Point_& p, const Point_& q, int n) {
984: return this->nJoin(p, q, n, Color_(), false);
985: };
986:
987: template <typename Point_, typename Marker_, typename Color_>
988: 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) {
989: Obj<supportSet> chain0 = supportSet();
990: Obj<supportSet> chain1 = supportSet();
991: chain0->insert(p);
992: chain1->insert(q);
993: return this->nJoin(chain0, chain1, n, color, useColor);
994: };
996: template <typename Point_, typename Marker_, typename Color_>
997: template<class InputSequence>
998: Obj<typename Sieve<Point_,Marker_,Color_>::supportSet> Sieve<Point_,Marker_,Color_>::nJoin(const Obj<InputSequence>& chain0, const Obj<InputSequence>& chain1, int n) {
999: return this->nJoin(chain0, chain1, n, Color_(), false);
1000: };
1002: template <typename Point_, typename Marker_, typename Color_>
1003: template<class InputSequence>
1004: 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){
1005: // The strategy is to compute the intersection of supports over the chains, remove the intersection
1006: // and use the remaining two parts -- two disjoined components of the symmetric difference of supports -- as the new chains.
1007: // The intersections at each stage are accumulated and their union is the join.
1008: // 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.
1009: Obj<supportSet> join = supportSet();
1010: Obj<supportSet> support;
1011: // std::cout << "Computing nJoin" << std::endl;
1012: // std::cout << " chain 0:" << std::endl;
1013: // for(typename InputSequence::iterator i_iter = chain0->begin(); i_iter != chain0->end(); ++i_iter) {
1014: // std::cout << " " << *i_iter << std::endl;
1015: // }
1016: // std::cout << " chain 1:" << std::endl;
1017: // for(typename InputSequence::iterator i_iter = chain1->begin(); i_iter != chain1->end(); ++i_iter) {
1018: // std::cout << " " << *i_iter << std::endl;
1019: // }
1020: if((chain0->size() != 0) && (chain1->size() != 0)) {
1021: for(int i = 0; i <= n; ++i) {
1022: // std::cout << "Level " << i << std::endl;
1023: // Compute the intersection of chains and put it in meet at the same time removing it from c and cc
1024: std::set<point_type> intersect;
1025: //std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<supportSet>(join.obj(), join->begin()));
1026: std::set_intersection(chain0->begin(), chain0->end(), chain1->begin(), chain1->end(), std::insert_iterator<std::set<point_type> >(intersect, intersect.begin()));
1027: join->insert(intersect.begin(), intersect.end());
1028: // std::cout << " Join set:" << std::endl;
1029: // for(typename supportSet::iterator i_iter = join->begin(); i_iter != join->end(); ++i_iter) {
1030: // std::cout << " " << *i_iter << std::endl;
1031: // }
1032: for(typename std::set<point_type>::iterator i_iter = intersect.begin(); i_iter != intersect.end(); ++i_iter) {
1033: chain0->erase(chain0->find(*i_iter));
1034: chain1->erase(chain1->find(*i_iter));
1035: }
1036: // 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.
1037: support = this->support(chain0);
1038: chain0->insert(support->begin(), support->end());
1039: if(chain0->size() == 0) {
1040: break;
1041: }
1042: // std::cout << " chain 0:" << std::endl;
1043: // for(typename InputSequence::iterator i_iter = chain0->begin(); i_iter != chain0->end(); ++i_iter) {
1044: // std::cout << " " << *i_iter << std::endl;
1045: // }
1046: support = this->support(chain1);
1047: chain1->insert(support->begin(), support->end());
1048: if(chain1->size() == 0) {
1049: break;
1050: }
1051: // std::cout << " chain 1:" << std::endl;
1052: // for(typename InputSequence::iterator i_iter = chain1->begin(); i_iter != chain1->end(); ++i_iter) {
1053: // std::cout << " " << *i_iter << std::endl;
1054: // }
1055: // If both supports are empty, we should quit
1056: }
1057: }
1058: return join;
1059: };
1061: template <typename Point_, typename Marker_, typename Color_>
1062: template<typename ostream_type>
1063: void Sieve<Point_,Marker_,Color_>::view(ostream_type& os, const char* label = NULL, bool rawData = false){
1064: if(label != NULL) {
1065: os << "Viewing Sieve '" << label << "':" << std::endl;
1066: }
1067: else {
1068: os << "Viewing a Sieve:" << std::endl;
1069: }
1070: if(!rawData) {
1071: os << "cap --> base:" << std::endl;
1072: Obj<typename traits::capSequence> cap = this->cap();
1073: for(typename traits::capSequence::iterator capi = cap->begin(); capi != cap->end(); ++capi) {
1074: Obj<typename traits::supportSequence> supp = this->support(*capi);
1075: for(typename traits::supportSequence::iterator suppi = supp->begin(); suppi != supp->end(); ++suppi) {
1076: os << *capi << "--(" << suppi.color() << ")-->" << *suppi << std::endl;
1077: }
1078: }
1079: os << "base <-- cap:" << std::endl;
1080: Obj<typename traits::baseSequence> base = this->base();
1081: for(typename traits::baseSequence::iterator basei = base->begin(); basei != base->end(); ++basei) {
1082: Obj<typename traits::coneSequence> cone = this->cone(*basei);
1083: for(typename traits::coneSequence::iterator conei = cone->begin(); conei != cone->end(); ++conei) {
1084: os << *basei << "<--(" << conei.color() << ")--" << *conei << std::endl;
1085: }
1086: }
1087: os << "cap --> (outdegree, marker, depth, height):" << std::endl;
1088: for(typename traits::capSequence::iterator capi = cap->begin(); capi != cap->end(); ++capi) {
1089: os << *capi << "-->" << capi.degree() << ", " << capi.marker() << ", " << capi.depth() << ", " << capi.height() << std::endl;
1090: }
1091: os << "base --> (indegree, marker, depth, height):" << std::endl;
1092: for(typename traits::baseSequence::iterator basei = base->begin(); basei != base->end(); ++basei) {
1093: os << *basei << "-->" << basei.degree() << ", " << basei.marker() << ", " << basei.depth() << ", " << basei.height() << std::endl;
1094: }
1095: }
1096: else {
1097: os << "'raw' arrow set:" << std::endl;
1098: for(typename traits::arrow_container_type::set_type::iterator ai = this->_arrows.set.begin(); ai != this->_arrows.set.end(); ai++)
1099: {
1100: typename traits::arrow_type arr = *ai;
1101: os << arr << std::endl;
1102: }
1103: os << "'raw' base set:" << std::endl;
1104: for(typename traits::base_container_type::set_type::iterator bi = this->_base.set.begin(); bi != this->_base.set.end(); bi++)
1105: {
1106: typename traits::base_container_type::traits::rec_type bp = *bi;
1107: os << bp << std::endl;
1108: }
1109: os << "'raw' cap set:" << std::endl;
1110: for(typename traits::cap_container_type::set_type::iterator ci = this->_cap.set.begin(); ci != this->_cap.set.end(); ci++)
1111: {
1112: typename traits::cap_container_type::traits::rec_type cp = *ci;
1113: os << cp << std::endl;
1114: }
1115: }
1116: };
1117: template <typename Point_, typename Marker_, typename Color_>
1118: void Sieve<Point_,Marker_,Color_>::view(const char* label = NULL, MPI_Comm comm = MPI_COMM_NULL) {
1119: ostringstream txt;
1121: if (this->debug()) {
1122: std::cout << "viewing a Sieve, comm = " << this->comm() << ", commRank = " << this->commRank() << std::endl;
1123: }
1124: if(label != NULL) {
1125: if(this->commRank() == 0) {
1126: txt << "viewing Sieve :'" << label << "'" << std::endl;
1127: }
1128: }
1129: else {
1130: if(this->commRank() == 0) {
1131: txt << "viewing a Sieve" << std::endl;
1132: }
1133: }
1134: if(this->commRank() == 0) {
1135: txt << "cap --> base:\n";
1136: }
1137: typename traits::capSequence cap = this->cap();
1138: typename traits::baseSequence base = this->base();
1139: if(cap.empty()) {
1140: txt << "[" << this->commRank() << "]: empty" << std::endl;
1141: }
1142: for(typename traits::capSequence::iterator capi = cap.begin(); capi != cap.end(); capi++) {
1143: const Obj<typename traits::supportSequence>& supp = this->support(*capi);
1144: const typename traits::supportSequence::iterator suppEnd = supp->end();
1146: for(typename traits::supportSequence::iterator suppi = supp->begin(); suppi != suppEnd; suppi++) {
1147: txt << "[" << this->commRank() << "]: " << *capi << "--(" << suppi.color() << ")-->" << *suppi << std::endl;
1148: }
1149: }
1150: PetscSynchronizedPrintf(this->comm(), txt.str().c_str());
1151: PetscSynchronizedFlush(this->comm());
1152: //
1153: ostringstream txt1;
1154: if(this->commRank() == 0) {
1155: txt1 << "base --> cap:\n";
1156: }
1157: if(base.empty()) {
1158: txt1 << "[" << this->commRank() << "]: empty" << std::endl;
1159: }
1160: for(typename traits::baseSequence::iterator basei = base.begin(); basei != base.end(); basei++) {
1161: const Obj<typename traits::coneSequence>& cone = this->cone(*basei);
1162: const typename traits::coneSequence::iterator coneEnd = cone->end();
1164: for(typename traits::coneSequence::iterator conei = cone->begin(); conei != coneEnd; conei++) {
1165: txt1 << "[" << this->commRank() << "]: " << *basei << "<--(" << conei.color() << ")--" << *conei << std::endl;
1166: }
1167: }
1168: //
1169: PetscSynchronizedPrintf(this->comm(), txt1.str().c_str());
1170: PetscSynchronizedFlush(this->comm());
1171: //
1172: ostringstream txt2;
1173: if(this->commRank() == 0) {
1174: txt2 << "cap <point, outdegree, marker, depth, height>:\n";
1175: }
1176: txt2 << "[" << this->commRank() << "]: [";
1177: for(typename traits::capSequence::iterator capi = cap.begin(); capi != cap.end(); capi++) {
1178: txt2 << " <" << *capi << ", " << capi.degree() << ", " << capi.marker() << ", " << capi.depth() << ", " << capi.height() << ">";
1179: }
1180: txt2 << " ]" << std::endl;
1181: //
1182: PetscSynchronizedPrintf(this->comm(), txt2.str().c_str());
1183: PetscSynchronizedFlush(this->comm());
1184: //
1185: ostringstream txt3;
1186: if(this->commRank() == 0) {
1187: txt3 << "base <point, indegree, marker, depth, height>:\n";
1188: }
1189: txt3 << "[" << this->commRank() << "]: [";
1190: for(typename traits::baseSequence::iterator basei = base.begin(); basei != base.end(); basei++) {
1191: txt3 << " <" << *basei << "," << basei.degree() << ", " << basei.marker() << ", " << basei.depth() << ", " << basei.height() << ">";
1192: }
1193: txt3 << " ]" << std::endl;
1194: //
1195: PetscSynchronizedPrintf(this->comm(), txt3.str().c_str());
1196: PetscSynchronizedFlush(this->comm());
1197: };
1198: //
1199: // Structural queries
1200: //
1201: template <typename Point_, typename Marker_, typename Color_>
1202: void Sieve<Point_,Marker_,Color_>::setMarker(const point_type& p, const marker_type& marker) {
1203: 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);
1204: 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);
1206: if (bIndex.find(p) != bIndex.end()) {
1207: bIndex.modify(bIndex.find(p), changeMarker(marker));
1208: }
1209: if (cIndex.find(p) != cIndex.end()) {
1210: cIndex.modify(cIndex.find(p), changeMarker(marker));
1211: }
1212: this->_markers->insert(marker);
1213: };
1215: template <typename Point_, typename Marker_, typename Color_>
1216: template <typename Sequence>
1217: void Sieve<Point_,Marker_,Color_>::setMarker(const Obj<Sequence>& points, const marker_type& marker) {
1218: for(typename Sequence::iterator p_iter = points->begin(); p_iter != points->end(); ++p_iter) {
1219: this->setMarker(*p_iter, marker);
1220: }
1221: };
1223: template <typename Point_, typename Marker_, typename Color_>
1224: int Sieve<Point_,Marker_,Color_>::depth() {
1225: return this->maxDepth;
1226: };
1227: template <typename Point_, typename Marker_, typename Color_>
1228: int Sieve<Point_,Marker_,Color_>::depth(const point_type& p) {
1229: 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);
1230: if (i.find(p) != i.end()) {
1231: return i.find(p)->depth;
1232: }
1233: return 0;
1234: };
1235: template <typename Point_, typename Marker_, typename Color_>
1236: template<typename InputSequence>
1237: int Sieve<Point_,Marker_,Color_>::depth(const Obj<InputSequence>& points) {
1238: 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);
1239: int maxDepth = 0;
1240:
1241: for(typename InputSequence::iterator iter = points->begin(); iter != points->end(); ++iter) {
1242: if (i.find(*iter) != i.end()) {
1243: maxDepth = std::max(maxDepth, i.find(*iter)->depth);
1244: }
1245: }
1246: return maxDepth;
1247: };
1248: template <typename Point_, typename Marker_, typename Color_>
1249: int Sieve<Point_,Marker_,Color_>::height() {
1250: return this->maxHeight;
1251: };
1252: template <typename Point_, typename Marker_, typename Color_>
1253: int Sieve<Point_,Marker_,Color_>::height(const point_type& p) {
1254: 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);
1255: if (i.find(p) != i.end()) {
1256: return i.find(p)->height;
1257: }
1258: return 0;
1259: };
1260: template <typename Point_, typename Marker_, typename Color_>
1261: template<typename InputSequence>
1262: int Sieve<Point_,Marker_,Color_>::height(const Obj<InputSequence>& points) {
1263: 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);
1264: int maxHeight = 0;
1265:
1266: for(typename InputSequence::iterator iter = points->begin(); iter != points->end(); ++iter) {
1267: if (i.find(*iter) != i.end()) {
1268: maxHeight = std::max(maxHeight, i.find(*iter)->height);
1269: }
1270: }
1271: return maxHeight;
1272: };
1274: template <typename Point_, typename Marker_, typename Color_>
1275: int Sieve<Point_,Marker_,Color_>::diameter() {
1276: int globalDiameter;
1277: int MPI_Allreduce(&this->graphDiameter, &globalDiameter, 1, MPI_INT, MPI_MAX, this->comm());
1278: CHKMPIERROR(ierr, ERRORMSG("Error in MPI_Allreduce"));
1279: return globalDiameter;
1280: };
1281: template <typename Point_, typename Marker_, typename Color_>
1282: int Sieve<Point_,Marker_,Color_>::diameter(const point_type& p) {
1283: return this->depth(p) + this->height(p);
1284: };
1286: template <typename Point_, typename Marker_, typename Color_>
1287: Obj<typename Sieve<Point_,Marker_,Color_>::traits::depthSequence> Sieve<Point_,Marker_,Color_>::depthStratum(int d) {
1288: if (d == 0) {
1289: return typename traits::depthSequence(::boost::multi_index::get<typename traits::cap_container_type::traits::depthMarkerTag>(this->_cap.set), d);
1290: } else {
1291: return typename traits::depthSequence(::boost::multi_index::get<typename traits::base_container_type::traits::depthMarkerTag>(this->_base.set), d);
1292: }
1293: };
1294: template <typename Point_, typename Marker_, typename Color_>
1295: Obj<typename Sieve<Point_,Marker_,Color_>::traits::depthSequence> Sieve<Point_,Marker_,Color_>::depthStratum(int d, marker_type m) {
1296: if (d == 0) {
1297: return typename traits::depthSequence(::boost::multi_index::get<typename traits::cap_container_type::traits::depthMarkerTag>(this->_cap.set), d, m);
1298: } else {
1299: return typename traits::depthSequence(::boost::multi_index::get<typename traits::base_container_type::traits::depthMarkerTag>(this->_base.set), d, m);
1300: }
1301: };
1302: template <typename Point_, typename Marker_, typename Color_>
1303: Obj<typename Sieve<Point_,Marker_,Color_>::traits::heightSequence> Sieve<Point_,Marker_,Color_>::heightStratum(int h) {
1304: if (h == 0) {
1305: return typename traits::heightSequence(::boost::multi_index::get<typename traits::base_container_type::traits::heightMarkerTag>(this->_base.set), h);
1306: } else {
1307: return typename traits::heightSequence(::boost::multi_index::get<typename traits::cap_container_type::traits::heightMarkerTag>(this->_cap.set), h);
1308: }
1309: };
1310: template <typename Point_, typename Marker_, typename Color_>
1311: Obj<typename Sieve<Point_,Marker_,Color_>::traits::heightSequence> Sieve<Point_,Marker_,Color_>::heightStratum(int h, marker_type m) {
1312: if (h == 0) {
1313: return typename traits::heightSequence(::boost::multi_index::get<typename traits::base_container_type::traits::heightMarkerTag>(this->_base.set), h, m);
1314: } else {
1315: return typename traits::heightSequence(::boost::multi_index::get<typename traits::cap_container_type::traits::heightMarkerTag>(this->_cap.set), h, m);
1316: }
1317: };
1318: template <typename Point_, typename Marker_, typename Color_>
1319: template<class InputSequence>
1320: void Sieve<Point_,Marker_,Color_>::__computeClosureHeights(const Obj<InputSequence>& points) {
1321: 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);
1322: 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);
1323: Obj<coneSet> modifiedPoints = coneSet();
1324:
1325: for(typename InputSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
1326: // Compute the max height of the points in the support of p, and add 1
1327: int h0 = this->height(*p_itor);
1328: int h1 = this->height(this->support(*p_itor)) + 1;
1329: if(h1 != h0) {
1330: 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);
1332: index.modify(index.find(*p_itor), changeHeight(h1));
1333: if (bIter != bIndex.end()) {
1334: bIndex.modify(bIter, changeHeight(h1));
1335: }
1336: if (h1 > this->maxHeight) this->maxHeight = h1;
1337: modifiedPoints->insert(*p_itor);
1338: }
1339: }
1340: // FIX: We would like to avoid the copy here with cone()
1341: if(modifiedPoints->size() > 0) {
1342: this->__computeClosureHeights(this->cone(modifiedPoints));
1343: }
1344: };
1345: template <typename Point_, typename Marker_, typename Color_>
1346: template<class InputSequence>
1347: void Sieve<Point_,Marker_,Color_>::__computeStarDepths(const Obj<InputSequence>& points) {
1348: 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);
1349: 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);
1350: Obj<supportSet> modifiedPoints = supportSet();
1351: for(typename InputSequence::iterator p_itor = points->begin(); p_itor != points->end(); ++p_itor) {
1352: // Compute the max depth of the points in the support of p, and add 1
1353: int d0 = this->depth(*p_itor);
1354: int d1 = this->depth(this->cone(*p_itor)) + 1;
1355: if(d1 != d0) {
1356: 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);
1358: index.modify(index.find(*p_itor), changeDepth(d1));
1359: if (cIter != cIndex.end()) {
1360: cIndex.modify(cIter, changeDepth(d1));
1361: }
1362: if (d1 > this->maxDepth) this->maxDepth = d1;
1363: modifiedPoints->insert(*p_itor);
1364: }
1365: }
1366: // FIX: We would like to avoid the copy here with cone()
1367: if(modifiedPoints->size() > 0) {
1368: this->__computeStarDepths(this->support(modifiedPoints));
1369: }
1370: };
1373: template <typename Point_, typename Marker_, typename Color_>
1374: void Sieve<Point_,Marker_,Color_>::stratify(bool show) {
1375: ALE_LOG_EVENT_BEGIN;
1376: // FIX: We would like to avoid the copy here with cone() and support()
1377: this->__computeClosureHeights(this->cone(this->leaves()));
1378: this->__computeStarDepths(this->support(this->roots()));
1379:
1380: Obj<typename traits::capSequence> base = this->base();
1382: for(typename traits::baseSequence::iterator b_iter = base->begin(); b_iter != base->end(); ++b_iter) {
1383: maxDepth = std::max(maxDepth, b_iter.depth());
1384: //b_iter.setDegree(this->cone(*b_iter)->size());
1385: this->_base.adjustDegree(*b_iter, this->cone(*b_iter)->size());
1386: }
1387: Obj<typename traits::capSequence> cap = this->cap();
1389: for(typename traits::capSequence::iterator c_iter = cap->begin(); c_iter != cap->end(); ++c_iter) {
1390: maxHeight = std::max(maxHeight, c_iter.height());
1391: //c_iter.setDegree(this->support(*c_iter)->size());
1392: this->_cap.adjustDegree(*c_iter, this->support(*c_iter)->size());
1393: }
1394: if (this->debug() || show) {
1395: // const typename ::boost::multi_index::index<StratumSet,point>::type& points = ::boost::multi_index::get<point>(this->strata);
1396: // for(typename ::boost::multi_index::index<StratumSet,point>::type::iterator i = points.begin(); i != points.end(); i++) {
1397: // std::cout << *i << std::endl;
1398: // }
1399: }
1400: ALE_LOG_EVENT_END;
1401: };
1402: //
1403: // Structural manipulation
1404: //
1405:
1406: } // namespace ALE
1408: #endif