--- 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__