Merged in Python branch dev
authorDmitriy Morozov <dmitriy@mrzv.org>
Sat, 27 Dec 2008 14:51:38 -0800
branchdev
changeset 105 051af83fba4c
parent 100 884f70adc576 (current diff)
parent 104 2cc1db3b98c6 (diff)
child 106 dfa74f2f2a76
Merged in Python branch
CMakeLists.txt
bindings/python/simplex.cpp
include/topology/filtration.h
include/topology/lowerstarfiltration.hpp
include/topology/persistence-diagram.h
include/topology/persistence-diagram.hpp
include/topology/simplex.h
include/topology/simplex.hpp
include/utilities/counter.h
include/utilities/types.h
--- a/CMakeLists.txt	Sat Dec 27 14:33:25 2008 -0800
+++ b/CMakeLists.txt	Sat Dec 27 14:51:38 2008 -0800
@@ -9,7 +9,7 @@
 option                      (use_synaps         "Build examples that use SYNAPS"        OFF)
 
 # Find everything that's always required
-find_package                (Boost REQUIRED COMPONENTS program_options serialization signals)
+find_package                (Boost REQUIRED COMPONENTS program_options python serialization signals)
 find_package                (Doxygen)
 if                          (use_dsrpdb)
     find_library            (dsrpdb_LIBRARY             NAMES dsrpdb)
@@ -105,3 +105,4 @@
 add_subdirectory            (examples)
 add_subdirectory            (tests)
 add_subdirectory            (tools)
+add_subdirectory            (bindings)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/CMakeLists.txt	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,1 @@
+add_subdirectory			(python)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/python/CMakeLists.txt	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,10 @@
+link_libraries              (${Boost_PYTHON_LIBRARY})
+include_directories         ("/usr/include/python2.6")
+link_directories            ("/usr/lib/python2.6")
+add_library                 (_dionysus SHARED 
+                                                dionysus.cpp 
+                                                filtration.cpp
+                                                chain.cpp
+                                                static-persistence.cpp
+                                                simplex.cpp)
+target_link_libraries       (_dionysus ${libraries})                                            
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/python/chain.cpp	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,18 @@
+#include <topology/chain.h>
+#include "python-static-persistence.h"
+#include <boost/python.hpp>
+
+using namespace boost::python;
+
+typedef     SPersistence::OrderDescriptor::Chains::Chain        VChain;
+
+
+VChain::const_iterator      begin(const VChain& c)              { return c.begin(); }
+VChain::const_iterator      end(const VChain& c)                { return c.end(); }
+
+void export_chain()
+{
+    class_<VChain>("Chain")
+        .def("__iter__",    range(&begin, &end))
+    ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/python/dionysus.cpp	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,28 @@
+#include <utilities/log.h>
+#include <boost/python.hpp>
+
+namespace bp = boost::python;
+
+void export_simplex();
+void export_filtration();
+void export_static_persistence();
+void export_chain();
+
+#ifdef LOGGING
+void            enable_log(std::string s)
+{
+    stdoutLog.subscribeTo(RLOG_CHANNEL(s.c_str()));
+}
+#endif
+
+BOOST_PYTHON_MODULE(_dionysus)
+{
+    export_simplex();
+    export_filtration();
+    export_static_persistence();
+    export_chain();
+
+#ifdef LOGGING
+    bp::def("enable_log",           &enable_log);
+#endif
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/python/filtration.cpp	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,73 @@
+#include <topology/filtration.h>
+#include <boost/iterator.hpp>
+#include "python-simplex.h"
+#include <iostream>
+
+#include <boost/python.hpp>
+using namespace boost::python;
+
+
+#include "python-filtration.h"      // defines ListFiltration, ListTraits, ListRandomAccessIterator
+
+// Filtration python iterator interface    
+class FiltrationPythonIterator:
+    public boost::iterator_adaptor<FiltrationPythonIterator,        // Derived
+                                   ListFiltration::Index,           // Base
+                                   unsigned>                        // Value
+{
+    public:
+        typedef                 FiltrationPythonIterator                                        Self;
+        typedef                 boost::iterator_adaptor<FiltrationPythonIterator,           
+                                                        ListFiltration::Index,     
+                                                        unsigned>                               Parent;
+
+                                FiltrationPythonIterator(ListFiltration::Index i):
+                                    Parent(i)                                                   {}
+
+    private:
+        friend class boost::iterator_core_access;
+
+        Parent::reference dereference() const
+        {
+            // FIXME: I hate the const_cast here, how do I get rid of it?
+            return const_cast<unsigned&>(this->base()->base().base());
+        }
+};
+
+FiltrationPythonIterator
+py_begin(const ListFiltration& lf)
+{ return lf.begin(); }
+
+FiltrationPythonIterator
+py_end(const ListFiltration& lf)
+{ return lf.end(); }
+
+    
+struct PythonCmp
+{
+    template<class T>
+    bool            operator()(T x1, T x2) const        { return cmp_(x1, x2) < 0; }
+
+                    PythonCmp(object cmp): cmp_(cmp)    {}
+
+    object cmp_;
+};
+
+boost::shared_ptr<ListFiltration>  init_from_list(list lst, object cmp)
+{
+    boost::shared_ptr<ListFiltration>  p(new ListFiltration(ListTraits::begin(lst),
+                                                            ListTraits::end(lst),
+                                                            PythonCmp(cmp)));
+    return p;
+}
+
+void export_filtration()
+{
+    class_<ListFiltration>("Filtration", no_init)
+        .def("__init__",        make_constructor(&init_from_list))
+        //.def("simplex", )
+
+        .def("__iter__",        range(&py_begin, &py_end))
+        .def("__len__",         &ListFiltration::size)
+    ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/python/python-filtration.h	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,61 @@
+#ifndef __PYTHON_FILTRATION_H__
+#define __PYTHON_FILTRATION_H__
+
+#include <topology/filtration.h>
+#include <boost/python.hpp>
+#include "python-simplex.h"
+
+namespace bp = boost::python;
+
+// Random access iterator into python's list (using integer indices)
+class ListRandomAccessIterator:
+    public boost::iterator_adaptor<ListRandomAccessIterator,                // Derived
+                                   boost::counting_iterator<unsigned>,      // Base
+                                   SimplexVD>                               // Value
+{
+    public:
+        typedef                 ListRandomAccessIterator                                        Self;
+        typedef                 boost::iterator_adaptor<ListRandomAccessIterator,           
+                                                        boost::counting_iterator<unsigned>,     
+                                                        SimplexVD>                              Parent;
+                    
+                                ListRandomAccessIterator()                                      {}
+
+                                ListRandomAccessIterator(bp::list l, unsigned i):
+                                    Parent(i), l_(l)                                            {}
+
+    private:
+        friend class boost::iterator_core_access;
+        friend class FiltrationPythonIterator;
+
+        Parent::reference       dereference() const
+        {
+            const SimplexVD& s = bp::extract<const SimplexVD&>(l_[*(this->base())]);
+            return const_cast<SimplexVD&>(s);       // FIXME: get rid of const_cast
+        }
+
+        bp::list                l_;
+};
+
+// ComplexTraits describing complexes of type list
+struct ListTraits
+{
+    typedef     bp::list                                        Complex;
+    typedef     SimplexVD                                       Simplex;
+    typedef     ListRandomAccessIterator                        Index;
+    typedef     std::less<Index>                                IndexComparison;
+
+    typedef     BinarySearchMap<Simplex, Index,
+                                Simplex::VertexComparison>      SimplexIndexMap;
+
+    static SimplexIndexMap      simplex_index_map(const Complex& l)             { return SimplexIndexMap(begin(l), end(l)); }
+    static SimplexIndexMap      simplex_index_map(Index bg, Index end)          { return SimplexIndexMap(bg, end); }
+
+    static unsigned             size(const Complex& l)                          { return bp::extract<unsigned>(l.attr("__len__")()); }
+    static Index                begin(const Complex& l)                         { return Index(l, 0); }
+    static Index                end(const Complex& l)                           { return Index(l, size(l)); }
+};
+
+typedef         Filtration<bp::list, unsigned, ListTraits>          ListFiltration;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/python/python-simplex.h	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,11 @@
+#ifndef __PYTHON_SIMPLEX_H__
+#define __PYTHON_SIMPLEX_H__
+
+#include <topology/simplex.h>
+
+typedef                             int                                         Vertex;
+typedef                             double                                      Data;
+//typedef                             Empty<>                                     Data;
+typedef                             Simplex<Vertex, Data>                       SimplexVD;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/python/python-static-persistence.h	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,9 @@
+#ifndef __PYTHON_STATIC_PERSISTENCE_H__
+#define __PYTHON_STATIC_PERSISTENCE_H__
+
+#include <topology/static-persistence.h>
+
+typedef         StaticPersistence<>             SPersistence;
+typedef         SPersistence::OrderElement      SPersistenceNode;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/python/simplex.cpp	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,85 @@
+#include <topology/simplex.h>
+#include <utilities/indirect.h>
+#include <iostream>
+
+#include <boost/python.hpp>
+#include <boost/python/stl_iterator.hpp>
+#include <boost/shared_ptr.hpp>
+using namespace boost::python;
+
+/* Various wrappers for exposing Simplex to Python */
+// `data` property
+template<class V, class T>
+typename Simplex<V,T>::Data         get_data(const Simplex<V,T>& s)             { return s.data(); }
+template<class V, class T>
+void                                set_data(Simplex<V,T>& s, 
+                                             typename Simplex<V,T>::Data d)     { s.data() = d; }
+// `vertices` property
+template<class V, class T>
+typename Simplex<V,T>::VertexContainer::const_iterator
+                                    vertices_begin(const Simplex<V,T>& s)       { return s.vertices().begin(); }
+template<class V, class T>
+typename Simplex<V,T>::VertexContainer::const_iterator
+                                    vertices_end(const Simplex<V,T>& s)         { return s.vertices().end(); }
+
+// Constructor from iterator
+template<class V, class T>
+boost::shared_ptr<Simplex<V,T> >    init_from_iterator(object iter)                      
+{ 
+    boost::shared_ptr<Simplex<V,T> > p(new Simplex<V,T>(stl_input_iterator<V>(iter), stl_input_iterator<V>()));
+    return p;
+}
+
+// Constructor from iterator and data
+template<class V, class T>
+boost::shared_ptr<Simplex<V,T> >    init_from_iterator_data(object iter, T data)                      
+{ 
+    boost::shared_ptr<Simplex<V,T> > p(new Simplex<V,T>(stl_input_iterator<V>(iter), stl_input_iterator<V>(), data));
+    return p;
+}
+
+/* Comparisons */
+// VertexComparison
+template<class V, class T>
+int                                 vertex_comparison(const Simplex<V,T>& a, const Simplex<V,T>& b)
+{
+    return ThreeOutcomeCompare<typename Simplex<V,T>::VertexComparison>().compare(a,b);
+}
+
+// DataComparison
+template<class V, class T>
+int                                 data_comparison(const Simplex<V,T>& a, const Simplex<V,T>& b)
+{
+    return ThreeOutcomeCompare<typename Simplex<V,T>::DataComparison>().compare(a,b);
+}
+
+// DataDimensionComparison
+template<class V, class T>
+int                                 data_dimension_comparison(const Simplex<V,T>& a, const Simplex<V,T>& b)
+{
+    return ThreeOutcomeCompare<DataDimensionComparison<Simplex<V,T> > >().compare(a,b);
+}
+
+#include "python-simplex.h"         // defines SimplexVD, Vertex, and Data
+
+void export_simplex()
+{
+    class_<SimplexVD>("Simplex")
+        .def("__init__",            make_constructor(&init_from_iterator<Vertex, Data>))
+        .def("__init__",            make_constructor(&init_from_iterator_data<Vertex, Data>))
+
+        .def("add",                 &SimplexVD::add)
+        .add_property("boundary",   range(&SimplexVD::boundary_begin, &SimplexVD::boundary_end))
+        .def("contains",            &SimplexVD::contains)
+        .def("join",                (void (SimplexVD::*)(const SimplexVD&)) &SimplexVD::join)
+        .def("dimension",           &SimplexVD::dimension)
+        .add_property("data",       &get_data<Vertex,Data>, &set_data<Vertex,Data>)
+        
+        .add_property("vertices",   range(&vertices_begin<Vertex,Data>, &vertices_end<Vertex,Data>))
+        .def(repr(self))
+    ;
+
+    def("vertex_cmp",               &vertex_comparison<Vertex, Data>);
+    def("data_cmp",                 &data_comparison<Vertex, Data>);
+    def("data_dim_cmp",             &data_dimension_comparison<Vertex, Data>);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bindings/python/static-persistence.cpp	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,37 @@
+#include <topology/static-persistence.h>
+#include "python-filtration.h"
+
+#include <boost/python.hpp>
+using namespace boost::python;
+
+#include "python-static-persistence.h"
+
+boost::shared_ptr<SPersistence>     init_from_filtration(object f)
+{
+    ListFiltration& lf = extract<ListFiltration&>(f);
+    boost::shared_ptr<SPersistence> p(new SPersistence(lf));
+    return p;
+}
+
+void                                pair_simplices(SPersistence& p)
+{
+    p.pair_simplices(); 
+}
+
+void export_static_persistence()
+{
+    class_<SPersistenceNode>("StaticPersistenceNode")
+        .def_readonly("pair",   &SPersistenceNode::pair)
+        .def("sign",            &SPersistenceNode::sign)
+        .def_readonly("cycle",  &SPersistenceNode::cycle)
+    ;
+
+    class_<SPersistence>("StaticPersistence", no_init)
+        .def("__init__",        make_constructor(&init_from_filtration))
+
+        .def("pair_simplices",  &pair_simplices)
+
+        .def("__iter__",        range(&SPersistence::begin, &SPersistence::end))
+        .def("__len__",         &SPersistence::size)
+    ;
+}
--- a/examples/alphashapes/alphashapes3d.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/examples/alphashapes/alphashapes3d.h	Sat Dec 27 14:51:38 2008 -0800
@@ -59,7 +59,6 @@
 		RealType					value() const						{ return CGAL::to_double(alpha_); }
 		RealValue					alpha() const						{ return alpha_; }
 		bool						attached() const					{ return attached_; }
-		Boundary                    boundary() const;
 
 		// Ordering
 		struct AlphaOrder
--- a/examples/alphashapes/alphashapes3d.hpp	Sat Dec 27 14:33:25 2008 -0800
+++ b/examples/alphashapes/alphashapes3d.hpp	Sat Dec 27 14:51:38 2008 -0800
@@ -118,16 +118,6 @@
 	alpha_ = CGAL::squared_radius(p1, p2, p3, p4);
 }
 
-AlphaSimplex3D::Boundary
-AlphaSimplex3D::boundary() const
-{
-	Boundary bdry;
-	Parent::Boundary pbdry = Parent::boundary();
-	for (Parent::Boundary::const_iterator cur = pbdry.begin(); cur != pbdry.end(); ++cur)
-		bdry.push_back(*cur);
-	return bdry;
-}
-
 
 bool 
 AlphaSimplex3D::AlphaOrder::
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/triangle/triangle.py	Sat Dec 27 14:51:38 2008 -0800
@@ -0,0 +1,29 @@
+from dionysus import Simplex, Filtration, StaticPersistence, \
+                     vertex_cmp, data_cmp, data_dim_cmp \
+#                    ,enable_log
+
+complex = [Simplex((0,),        0),                 # A
+           Simplex((1,),        1),                 # B
+           Simplex((2,),        2),                 # C
+           Simplex((0,1),       2.5),               # AB
+           Simplex((1,2),       2.9),               # BC
+           Simplex((0,2),       3.5),               # CA
+           Simplex((0,1,2),     5)]                 # ABC
+
+print "Complex:", complex
+print "Vertex: ", sorted(complex, vertex_cmp)
+print "Data:   ", sorted(complex, data_cmp)
+print "DataDim:", sorted(complex, data_dim_cmp)
+
+complex.sort(vertex_cmp)
+
+f = Filtration(complex, data_cmp)
+for i in f: print i,
+print
+
+#enable_log("topology/persistence")
+p = StaticPersistence(f)
+p.pair_simplices()
+for i in p: 
+    print i.sign()#, i.pair
+    #for ii in i.cycle: print ii
--- a/include/topology/dynamic-persistence.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/topology/dynamic-persistence.h	Sat Dec 27 14:51:38 2008 -0800
@@ -52,7 +52,7 @@
 // TODO: perhaps Consistency should be wrapped into a ConsistencyDescriptor that somehow knows how to initialize it. 
 // That way one could provide a simple consistency descriptor that just stored some integers describing the original 
 // position, or one could provide consistency that is references into the complex
-template<class Data_ =                  Empty, 
+template<class Data_ =                  Empty<>, 
          class OrderDescriptor_ =       VectorOrderDescriptor<>,
          class ConsistencyIndex_ =      size_t,
          class ConsistencyComparison_ = std::less<ConsistencyIndex_> >
--- a/include/topology/filtration.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/topology/filtration.h	Sat Dec 27 14:51:38 2008 -0800
@@ -31,7 +31,6 @@
         typedef                 typename ComplexTraits::Index                   ComplexIndex;
         typedef                 typename ComplexTraits::Simplex                 Simplex;
         typedef                 typename ComplexTraits::SimplexIndexMap         SimplexIndexMap;
-        typedef                 typename Simplex::Boundary                      SimplexBoundary;
         typedef                 std::vector<IntermediateIndex>                  IndexBoundary;
 
         // Typedefs: Order
--- a/include/topology/filtration.hpp	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/topology/filtration.hpp	Sat Dec 27 14:51:38 2008 -0800
@@ -1,11 +1,12 @@
 #include "utilities/containers.h"
+#include <boost/iterator/counting_iterator.hpp>
 
 template<class C, class I, class CT>
 template<class Comparison>
 Filtration<C,I,CT>::
 Filtration(ComplexIndex bg, ComplexIndex end, const Comparison& cmp):
-    order_(RecursiveIterator<ComplexIndex>(bg), 
-           RecursiveIterator<ComplexIndex>(end)),
+    order_(boost::counting_iterator<ComplexIndex>(bg), 
+           boost::counting_iterator<ComplexIndex>(end)),
     reverse_order_(order_.size()),
     complex_order_map_(bg, reverse_order_.begin()),
     simplex_index_map_(bg, end)
@@ -22,11 +23,10 @@
 boundary(const Index& i, Cycle& bdry, const Map& map) const
 {
     AssertMsg(bdry.empty(), "We are initializing the boundary from scratch");
-    SimplexBoundary simplex_bdry = (*i)->boundary();
-    ContainerTraits<Cycle>::reserve(bdry, simplex_bdry.size());
+    ContainerTraits<Cycle>::reserve(bdry, (*i)->boundary_end() - (*i)->boundary_begin());
     typename Map::template rebind_from<IntermediateIndex>::other    order_bdry_map(0, map.to());
 
-    for (typename SimplexBoundary::const_iterator cur = simplex_bdry.begin(); cur != simplex_bdry.end(); ++cur)
+    for (typename Simplex::BoundaryIterator cur = (*i)->boundary_begin(); cur != (*i)->boundary_end(); ++cur)
     {
         //std::cout << *cur << std::endl;
         //std::cout << simplex_index_map_[*cur] - complex_order_map_.from() << std::endl;
--- a/include/topology/lowerstarfiltration.hpp	Sat Dec 27 14:33:25 2008 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-#include "utilities/counter.h"
-
-/* Implementations */
-
-#ifdef LOGGING
-static rlog::RLogChannel* rlLowerStar = 				DEF_CHANNEL("lowerstar", rlog::Log_Debug);
-#endif // LOGGING
-
-#ifdef COUNTERS
-static Counter*  cLowerStarTransposition =		 		GetCounter("lowerstar");
-static Counter*  cLowerStarChangedAttachment =		 	GetCounter("lowerstar/ChangedAttachment");
-#endif // COUNTERS
-
-
-/**
- * Copies vertices [begin, end), orders them by cmp, and 
- * records which vineyard to use in case of transpositions.
- */
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-template<class VertexCmp>
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-LowerStarFiltration(VertexIndex begin, VertexIndex end, const VertexCmp& cmp, Vineyard* vineyard):
-	Parent(vineyard)
-{
-	// Record VertexIndexes in a temporary list
-	typedef std::list<VertexIndex> VertexIndexList;
-	VertexIndexList tmp_list;
-	while (begin != end)
-		tmp_list.push_back(begin++);
-
-	// Sort the temporary list
-	tmp_list.sort(cmp);
-
-	// Record vertex order
-	for(typename VertexIndexList::const_iterator cur = tmp_list.begin(); cur != tmp_list.end(); ++cur)
-		(*cur)->set_order(vertex_order.push_back(VertexDescriptor(*cur, Parent::append(Simplex(0, *cur)))));
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-typename LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::Index 
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-append(const Simplex& s)
-{
-	AssertMsg(s.dimension() != 0, "All vertices must have been inserted in the constructor");
-	
-	// Find the highest vertex
-	typename Simplex::VertexContainer::const_iterator cur = s.vertices().begin(), max = cur++;
-	for (; cur != s.vertices().end(); ++cur)
-		if (!vertex_cmp((*cur)->get_order(), (*max)->get_order()))
-			max = cur;
-
-	Index ms = (*max)->get_order()->simplex_index;	Index prior;
-	do { prior = ms++; } while (ms->dimension() <= s.dimension() && ms != Parent::end() && ms->get_attachment() == *max);
-	
-	Index i = Parent::insert(prior, s);
-	i->set_attachment(*max);
-
-	return i;
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-bool
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::SimplexAttachmentComparison::
-operator()(const Simplex& first, const Simplex& second) const
-{
-	int cmp = vertex_cmp.compare(first.get_attachment()->get_order(), second.get_attachment()->get_order());
-	if (cmp == 0)
-		return first.dimension() < second.dimension();
-	else
-		return cmp == -1;
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-bool 
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-transpose_vertices(const VertexOrderIndex& order)
-{
-	Count(cLowerStarTransposition);
-	rLog(rlLowerStar, "Transposing vertices (%s, %s)", 
-					  tostring(order->vertex_index).c_str(),
-					  tostring(boost::next(order)->vertex_index).c_str());
-
-	Index i = order->simplex_index;
-	Index i_prev = boost::prior(i);
-	Index i_next = boost::next(order)->simplex_index;
-	Index i_next_prev = boost::prior(i_next);			// transpositions are done in terms of the first index in the pair
-	Index j = boost::next(i_next);
-	
-	const VertexIndex& v_i = order->vertex_index;
-	const VertexIndex& v_i_next = boost::next(order)->vertex_index;
-	bool nbghrs = neighbors(v_i, v_i_next);
-	
-	bool result = false;
-	
-	// First, move the vertex --- this can be sped up if we devise special "vertex transpose" operation
-	while (i_next_prev != i_prev)						
-	{ 
-		result |= transpose(i_next_prev);
-		i_next_prev = boost::prior(i_next);
-	}
-	rLog(rlLowerStar, "Done moving the vertex");
-
-	// Second, move the simplices attached to it
-	rLog(rlLowerStar, "Moving attached simplices");
-	while (j != Parent::end() && j->get_attachment() == v_i_next)
-	{
-		rLog(rlLowerStar, "  Considering %s", tostring(*j).c_str());
-		if (nbghrs && j->contains(v_i))			// short circuit
-		{
-			Count(cLowerStarChangedAttachment);
-			rLog(rlLowerStar, "  Attachment changed for %s", tostring(*j).c_str());
-			j->set_attachment(v_i);
-			++j;
-			continue;
-		}	
-
-		Index j_prev = j; ++j;
-		while ((--j_prev)->get_attachment() != v_i_next) 		// i.e., until we have reached v_i_next 
-															// (and the simplices that follow it) again
-		{
-			rLog(rlLowerStar, "    Moving: %s, %s", 
-							  tostring(*j_prev).c_str(), tostring(*boost::next(j_prev)).c_str());
-			AssertMsg(j_prev->get_attachment() == v_i, "Simplex preceding the one being moved must be attached to v_i");
-			result |= transpose(j_prev);
-			--j_prev;
-		}
-	}
-	rLog(rlLowerStar, "Done moving attached simplices");
-	vertex_order.swap(order, boost::next(order));
-	
-	return result;
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-bool 
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-transpose(Index i)
-{
-	Index j = boost::next(i);
-	
-	rLog(rlLowerStar, "    Transposing (%s, %s) and (%s, %s)", 
-					  tostring(*i).c_str(), tostring(*(i->pair())).c_str(),
-					  tostring(*j).c_str(), tostring(*(j->pair())).c_str());
-
-	assert_pairing(i);
-	assert_pairing(j);
-
-	bool res = Parent::transpose(i, false);
-	rLog(rlLowerStar, "    %s: %s, %s: %s",
-					  tostring(*j).c_str(), tostring(*(j->pair())).c_str(),
-					  tostring(*i).c_str(), tostring(*(i->pair())).c_str());
-
-	assert_pairing(j);
-	assert_pairing(i);
-
-	return res;
-}
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-void 
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-assert_pairing(Index i)
-{
-#ifndef NDEBUG
-	AssertMsg(i != Parent::end(), "Cannot assert pairing of end()");
-	if (!i->sign())
-	{
-		if (i->pair() != i->cycle().top(Parent::get_cycles_cmp()))
-		{
-			rLog(rlLowerStar, "i (negative): %s", tostring(*i).c_str());
-			rLog(rlLowerStar, "pair(i): %s", tostring(*(i->pair())).c_str());
-			rLog(rlLowerStar, "i->cycle().top(): %s", 
-							  tostring(*(i->cycle().top(Parent::get_cycles_cmp()))).c_str());
-			AssertMsg(0, "Pairing not matching the matrix at %s", tostring(*i).c_str());
-		}
-	} else
-	{
-		if (i->pair() != i)
-		{
-			if (i->pair()->cycle().top(Parent::get_cycles_cmp()) != i)
-			{
-				rLog(rlLowerStar, "i (positive): %s", tostring(*i).c_str());
-				rLog(rlLowerStar, "pair(i): %s", tostring(*(i->pair())).c_str());
-				rLog(rlLowerStar, "pair(i)->cycle(): %s", tostring(i->pair()->cycle()).c_str());
-				rLog(rlLowerStar, "pair->cycle().top(): %s", tostring(*(i->pair()->cycle().top(Parent::get_cycles_cmp()))).c_str());
-				AssertMsg(0, "Pairing not matching the matrix at %s", tostring(*(i->pair())).c_str());
-			}
-		}
-	}
-#endif
-}
-
-
-template<class VI, class Smplx, class FltrSmplx, class Vnrd>
-template<class Archive>
-void 
-LowerStarFiltration<VI,Smplx,FltrSmplx,Vnrd>::
-load(Archive& ar, version_type )
-{
-/*
-	ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(Parent);
-	
-	// Count the number of vertices
-	VertexIndex num_vertices = 0;
-	for (Index cur = begin(); cur != end(); ++cur)
-		if (dimension(cur) == 0)	
-			num_vertices++;
-
-	// Second pass to record vertex_order
-	vertex_order.resize(num_vertices);
-	inverse_vertex_order.resize(num_vertices);
-	num_vertices = 0;
-	for (Index cur = begin(); cur != end(); ++cur)
-	{
-		if (dimension(cur) == 0)
-		{
-			vertex_order[num_vertices].index = cur;
-			vertex_order[num_vertices].vertex_index = *(cur->get_vertices().begin());
-			inverse_vertex_order[vertex_order[num_vertices].vertex_index] = num_vertices;
-			++num_vertices;
-		}
-	}
-*/
-}
-
-
--- a/include/topology/order.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/topology/order.h	Sat Dec 27 14:51:38 2008 -0800
@@ -3,6 +3,7 @@
 
 #include "cycles.h"
 #include "utilities/types.h"
+#include "utilities/indirect.h"
 
 #include <vector>
 #include <list>
@@ -20,7 +21,7 @@
  * That prevents it from performing efficient insertions.
  */
 template<class Chains_ =    VectorChains<>,
-         class Data_ =      Empty>
+         class Data_ =      Empty<> >
 struct VectorOrderDescriptor: 
     public Chains_::template rebind<typename OrderTraits<VectorOrderDescriptor<Chains_, Data_> >::Index>::other,
     public Data_
--- a/include/topology/persistence-diagram.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/topology/persistence-diagram.h	Sat Dec 27 14:51:38 2008 -0800
@@ -15,7 +15,7 @@
  *
  * Stores birth-death pair plus any additional information provided by `Data` template parameter.
  */
-template<class Data_ = Empty>
+template<class Data_ = Empty<> >
 class PDPoint
 {
     public:
@@ -70,7 +70,7 @@
  * Stores birth-death pairs, i.e. points in the extended plane. Each point can also store 
  * additional information described by `Data_` template parameter.
  */
-template<class Data_ = Empty>
+template<class Data_ = Empty<> >
 class PersistenceDiagram
 {
     public:
--- a/include/topology/persistence-diagram.hpp	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/topology/persistence-diagram.hpp	Sat Dec 27 14:51:38 2008 -0800
@@ -128,7 +128,7 @@
  * Some structures to compute bottleneck distance between two persistence diagrams (in bottleneck_distance() function below) 
  * by setting up bipartite graphs, and finding maximum cardinality matchings in them using Boost Graph Library.
  */
-#include <utilities/indirect.h>
+#include <boost/iterator/counting_iterator.hpp>
 #include <boost/graph/adjacency_list.hpp>
 #include <boost/graph/max_cardinality_matching.hpp>
 
@@ -228,10 +228,11 @@
     //    std::cout << "Edge: " << edges[i].first << " " << edges[i].second << " " << edges[i].distance << std::endl;
 
     // Perform cardinality based binary search
-    RecursiveIterator<EV_const_iterator> bdistance = std::upper_bound(RecursiveIterator<EV_const_iterator>(edges.begin()), 
-                                                     RecursiveIterator<EV_const_iterator>(edges.end()), 
-                                                     edges.begin(),
-                                                     CardinaliyComparison(max_size, edges.begin()));
+    typedef boost::counting_iterator<EV_const_iterator>         EV_counting_const_iterator;
+    EV_counting_const_iterator bdistance = std::upper_bound(EV_counting_const_iterator(edges.begin()), 
+                                                            EV_counting_const_iterator(edges.end()), 
+                                                            edges.begin(),
+                                                            CardinaliyComparison(max_size, edges.begin()));
     
     return (*bdistance)->distance;
 }
--- a/include/topology/simplex.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/topology/simplex.h	Sat Dec 27 14:51:38 2008 -0800
@@ -14,6 +14,7 @@
 #include "utilities/types.h"
 
 #include <boost/compressed_pair.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
 #include <boost/serialization/access.hpp>
 
 
@@ -29,7 +30,7 @@
  *
  * \ingroup topology
  */
-template<class V, class T = Empty>
+template<class V, class T = Empty<> >
 class Simplex
 {
     public:
@@ -43,8 +44,8 @@
         typedef     V                                                               Vertex;
         typedef     T                                                               Data;
         typedef     Simplex<Vertex, Data>                                           Self;
-        typedef     std::list<Self>                                                 Boundary;
-        
+        class BoundaryIterator;
+
         /* Typedefs: Internal representation
          *
          *    VertexContainer -     internal representation of the vertices
@@ -79,9 +80,10 @@
         /// \name Core 
         /// @{
         ///
-        /// Function: boundary()
-        /// Returns the boundary of the simplex (of type Boundary)
-        Boundary                boundary() const;
+        /// Functions: boundary_begin(), boundary_end()
+        /// Returns the iterators over the boundary of the simplex
+        BoundaryIterator        boundary_begin() const;
+        BoundaryIterator        boundary_end() const;
         /// Function: dimension()
         /// Returns the dimension of the simplex
         Dimension               dimension() const                                   { return vertices().size() - 1; }
@@ -93,7 +95,7 @@
         
         /// \name Vertex manipulation
         /// @{
-        bool                    contains(const Vertex& v) const;
+        //bool                    contains(const Vertex& v) const;
         bool                    contains(const Self& s) const;
         void                    add(const Vertex& v);
         template<class Iterator>
--- a/include/topology/simplex.hpp	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/topology/simplex.hpp	Sat Dec 27 14:51:38 2008 -0800
@@ -7,25 +7,58 @@
 
 /* Implementations */
 
+template<class V, class T>
+struct Simplex<V,T>::BoundaryIterator: public boost::iterator_adaptor<BoundaryIterator,                                 // Derived
+                                                                      typename VertexContainer::const_iterator,         // Base
+                                                                      Simplex<V,T>,                                     // Value
+                                                                      boost::use_default,
+                                                                      Simplex<V,T> >
+{
+    public:
+        typedef     typename VertexContainer::const_iterator                Iterator;
+        typedef     boost::iterator_adaptor<BoundaryIterator,
+                                            Iterator,
+                                            Simplex<V,T>,
+                                            boost::use_default,
+                                            Simplex<V,T> >                  Parent;
+                    
+                    BoundaryIterator()                                      {}
+        explicit    BoundaryIterator(Iterator iter, const VertexContainer& vertices):
+                        Parent(iter), vertices_(vertices)                   {}
+    
+    private:
+        friend class    boost::iterator_core_access;
+        Simplex<V,T>    dereference() const                                 
+        { 
+            typedef     std::not_equal_to<Vertex>                           NotEqualVertex;
+
+            return      Self(boost::make_filter_iterator(std::bind2nd(NotEqualVertex(), *(this->base())), vertices_.begin(), vertices_.end()),
+                             boost::make_filter_iterator(std::bind2nd(NotEqualVertex(), *(this->base())), vertices_.end(),   vertices_.end()));
+        }
+        
+        const VertexContainer&      vertices_;
+};
+
 /* Simplex */
 template<class V, class T>
-typename Simplex<V,T>::Boundary 
+typename Simplex<V,T>::BoundaryIterator
 Simplex<V,T>::
-boundary() const
+boundary_begin() const
 {
-    typedef         std::not_equal_to<Vertex>                           NotEqualVertex;
-
-    Boundary bdry;
-    if (dimension() == 0) return bdry;
-    
-    for (typename VertexContainer::const_iterator cur = vertices().begin(); cur != vertices().end(); ++cur)
-        bdry.push_back(Self(boost::make_filter_iterator(std::bind2nd(NotEqualVertex(), *cur), vertices().begin(), vertices().end()),
-                            boost::make_filter_iterator(std::bind2nd(NotEqualVertex(), *cur), vertices().end(),   vertices().end())));
-    
-    return bdry;
+    if (dimension() == 0)   return boundary_end();
+    return BoundaryIterator(vertices().begin(), vertices());
 }
 
 template<class V, class T>
+typename Simplex<V,T>::BoundaryIterator
+Simplex<V,T>::
+boundary_end() const
+{
+    return BoundaryIterator(vertices().end(), vertices());
+}
+
+#if 0
+template<class V, class T>
 bool
 Simplex<V,T>::
 contains(const Vertex& v) const
@@ -34,6 +67,7 @@
     typename VertexContainer::const_iterator location = std::lower_bound(vertices().begin(), vertices().end(), v); 
     return ((location != vertices().end()) && (*location == v)); 
 }
+#endif
  
 template<class V, class T>
 bool
--- a/include/topology/static-persistence.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/topology/static-persistence.h	Sat Dec 27 14:51:38 2008 -0800
@@ -15,7 +15,7 @@
  *   OrderDescriptor_ -     class describing how the order is stored; it defaults to <VectorOrderDescriptor> 
  *                          which serves as a prototypical class
  */
-template<class Data_ = Empty,
+template<class Data_ = Empty<>,
          class OrderDescriptor_ =   VectorOrderDescriptor<> >
 class StaticPersistence
 {
--- a/include/utilities/counter.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/utilities/counter.h	Sat Dec 27 14:51:38 2008 -0800
@@ -21,7 +21,6 @@
     #define     CountBy(x,y)                do { x->count += y; } while (0)
     #define     SetFrequency(x, freq)       do { x->frequency = freq; } while (0)
     #define     SetTrigger(x, y)            do { x->trigger = y; } while(0)
-#endif // COUNTERS
 
 
 #include <map>
@@ -76,5 +75,7 @@
 
 #include "counter.hpp"
 
+#endif // COUNTERS
+
 
 #endif // __COUNTER_H__
--- a/include/utilities/indirect.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/utilities/indirect.h	Sat Dec 27 14:51:38 2008 -0800
@@ -37,30 +37,4 @@
     }
 };
 
-template<class Iterator_>
-class RecursiveIterator: public boost::iterator_adaptor<RecursiveIterator<Iterator_>,       // Derived
-                                                        Iterator_,                          // Base
-                                                        Iterator_>                          // Value
-{
-    private:
-        struct      enabler                                                 {};
-
-    public:
-        typedef     Iterator_                                               Iterator;
-        typedef     boost::iterator_adaptor<RecursiveIterator<Iterator>, 
-                                                              Iterator, 
-                                                              Iterator>     Parent;
-
-                    RecursiveIterator()                                     {}
-        explicit    RecursiveIterator(Iterator iter):
-                        Parent(iter)                                        {}
-    
-    private:
-        friend class    boost::iterator_core_access;
-        typename Parent::reference       
-                        dereference() const                                 { return const_cast<typename Parent::reference>(this->base()); }
-        // FIXME: I dislike to const_cast, but it's not obvious how to get rid of it
-};
-
-
 #endif // __INDIRECT_H__
--- a/include/utilities/types.h	Sat Dec 27 14:33:25 2008 -0800
+++ b/include/utilities/types.h	Sat Dec 27 14:51:38 2008 -0800
@@ -6,7 +6,7 @@
 
 /* Types */
 typedef 	bool					Sign;
-typedef		unsigned short int		Dimension;
+typedef		short int		        Dimension;
 const 		Sign	 				POS = true;
 const 		Sign					NEG = false;
 typedef		double					RealType;
@@ -16,8 +16,13 @@
 
 typedef 	const unsigned int&		version_type;
 
+// Empty is made a template so that we don't have to compile and deal with a library
+// solely for its operator<<(out, e) function
+template<typename T = void>
 struct      Empty                   {};
-std::ostream& operator<<(std::ostream& out, Empty e) { return out; }
+
+template<typename T>
+std::ostream& operator<<(std::ostream& out, Empty<T> e) { return out; }
 
 enum        SwitchType
 {
@@ -32,17 +37,15 @@
             Case4       = 0x20,
 };
 
-
 // Nothing to do for serializing Empty, but still need to provide this function
 namespace boost {
 namespace serialization {
 
-template<class Archive>
-void serialize(Archive & ar, Empty&, const unsigned int )
+template<class Archive, class T>
+void serialize(Archive & ar, Empty<T>&, const unsigned int )
 {}
 
 } // namespace serialization
 } // namespace boost
 
-
 #endif // __TYPES_H__