Changes in Python Bindings:
* the exposed C++ simplex has Empty data
* Python Simplex constructor with data as well as data-based
comparison functions are implemented in pure Python
--- a/bindings/python/dionysus/__init__.py Sat Apr 11 10:29:53 2009 -0700
+++ b/bindings/python/dionysus/__init__.py Mon Apr 13 20:38:46 2009 -0700
@@ -2,18 +2,27 @@
from distances import *
-#def init_with_data(s,v, d = None):
-# s._cpp_init_(v)
-# if d is not None:
-# s.data = d
-#
-#Simplex._cpp_init_ = Simplex.__init__
-#Simplex.__init__ = init_with_data
-#
-#def data_cmp(s1, s2):
-# return cmp(s1.data,s2.data)
-#
-#def data_dim_cmp(s1,s2):
-# dim_cmp = cmp(s1.dimension(), s2.dimension())
-# if dim_cmp: return dim_cmp
-# else: return data_cmp(s1,s2)
+def init_with_data(self, v, d = None):
+ self._cpp_init_(v)
+ if d is not None:
+ self.data = d
+
+def repr_with_data(self):
+ str = self._cpp_repr_()
+ if hasattr(self, 'data'):
+ str += '%f' % self.data
+ return str
+
+Simplex._cpp_init_ = Simplex.__init__
+Simplex.__init__ = init_with_data
+Simplex._cpp_repr_ = Simplex.__repr__
+Simplex.__repr__ = repr_with_data
+
+
+def data_cmp(s1, s2):
+ return cmp(s1.data, s2.data)
+
+def data_dim_cmp(s1,s2):
+ dim_cmp = cmp(s1.dimension(), s2.dimension())
+ if dim_cmp: return dim_cmp
+ else: return data_cmp(s1,s2)
--- a/bindings/python/python-filtration.h Sat Apr 11 10:29:53 2009 -0700
+++ b/bindings/python/python-filtration.h Mon Apr 13 20:38:46 2009 -0700
@@ -11,13 +11,17 @@
class ListRandomAccessIterator:
public boost::iterator_adaptor<ListRandomAccessIterator, // Derived
boost::counting_iterator<unsigned>, // Base
- SimplexVD> // Value
+ SimplexObject, // Value
+ boost::use_default,
+ SimplexObject>
{
public:
typedef ListRandomAccessIterator Self;
typedef boost::iterator_adaptor<ListRandomAccessIterator,
boost::counting_iterator<unsigned>,
- SimplexVD> Parent;
+ SimplexObject,
+ boost::use_default,
+ SimplexObject> Parent;
ListRandomAccessIterator() {}
@@ -28,11 +32,7 @@
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
- }
+ Parent::reference dereference() const { return bp::object(l_[*(this->base())]); }
bp::list l_;
};
@@ -41,17 +41,17 @@
struct ListTraits
{
typedef bp::list Complex;
- typedef SimplexVD Simplex;
+ typedef SimplexObject Simplex;
typedef ListRandomAccessIterator Index;
typedef std::less<Index> IndexComparison;
- typedef BinarySearchMap<Simplex, Index,
- Simplex::VertexComparison> SimplexIndexMap;
+ typedef BinarySearchMap<SimplexVD, Index,
+ SimplexVD::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 unsigned size(const Complex& l) { return bp::len(l); }
static Index begin(const Complex& l) { return Index(l, 0); }
static Index end(const Complex& l) { return Index(l, size(l)); }
};
--- a/bindings/python/python-rips.h Sat Apr 11 10:29:53 2009 -0700
+++ b/bindings/python/python-rips.h Mon Apr 13 20:38:46 2009 -0700
@@ -92,11 +92,11 @@
bp::stl_input_iterator<IndexType>(seq), bp::stl_input_iterator<IndexType>());
}
- int cmp(const SimplexVD& s1, const SimplexVD& s2) const
- { return cmp_.compare(s1, s2); }
+ int cmp(const SimplexObject& s1, const SimplexObject& s2) const { return cmp_native(s1, s2); }
+ int cmp_native(const SimplexVD& s1, const SimplexVD& s2) const { return cmp_.compare(s1, s2); }
- DistanceType eval(const SimplexVD& s) const
- { return eval_(s); }
+ DistanceType eval(const SimplexObject& s) const { return eval_native(s); }
+ DistanceType eval_native(const SimplexVD& s) const { return eval_(s); }
private:
DistancesWrapper distances_;
--- a/bindings/python/python-simplex.h Sat Apr 11 10:29:53 2009 -0700
+++ b/bindings/python/python-simplex.h Mon Apr 13 20:38:46 2009 -0700
@@ -3,9 +3,59 @@
#include <topology/simplex.h>
+#include <boost/python.hpp>
+#include <boost/python/stl_iterator.hpp>
+namespace bp = boost::python;
+
+
+/**
+ * SimplexVD is a base class for Python simplices (it's exposed to python as Simplex)
+ *
+ * SimplexObject is the representation of Python simplices in C++; i.e. it wraps bp::object and exposes a simplex-like interface.
+ */
typedef int Vertex;
-typedef double Data;
-//typedef Empty<> Data;
+// typedef double Data;
+typedef Empty<> Data;
typedef Simplex<Vertex, Data> SimplexVD;
+
+// Wrapper around bp::object that acts like a simplex
+class SimplexObject: public bp::object
+{
+ public:
+ typedef SimplexObject Self;
+ typedef bp::object Parent;
+ typedef SimplexVD::BoundaryIterator BoundaryIterator;
+
+
+ SimplexObject(Parent o = Parent()): Parent(o) {}
+
+ BoundaryIterator boundary_begin() const { return bp::extract<const SimplexVD&>(*this)().boundary_begin(); }
+ BoundaryIterator boundary_end() const { return bp::extract<const SimplexVD&>(*this)().boundary_end(); }
+
+ operator SimplexVD() const { return bp::extract<const SimplexVD&>(*this); }
+ operator bp::object() const { return *this; }
+
+ bp::object getattribute(const char* name) const { return this->attr(name); }
+
+ class VertexComparison: public SimplexVD::VertexComparison
+ {
+ public:
+ typedef Self first_argument_type;
+ typedef Self second_argument_type;
+ typedef bool result_type;
+
+ bool operator()(const SimplexObject& s1, const SimplexObject& s2) const
+ { return SimplexVD::VertexComparison::operator()(bp::extract<const SimplexVD&>(s1), bp::extract<const SimplexVD&>(s2)); }
+ };
+};
+
+struct SimplexObjectToSimplexVD
+{
+ static PyObject* convert (const SimplexObject& so)
+ {
+ return (PyObject*) &so;
+ }
+};
+
#endif
--- a/bindings/python/rips.cpp Sat Apr 11 10:29:53 2009 -0700
+++ b/bindings/python/rips.cpp Mon Apr 13 20:38:46 2009 -0700
@@ -26,6 +26,8 @@
.def("edge_cofaces", &RipsWithDistances::edge_cofaces_candidates)
.def("cmp", &RipsWithDistances::cmp)
+ .def("cmp", &RipsWithDistances::cmp_native)
.def("eval", &RipsWithDistances::eval)
+ .def("eval", &RipsWithDistances::eval_native)
;
}
--- a/bindings/python/simplex.cpp Sat Apr 11 10:29:53 2009 -0700
+++ b/bindings/python/simplex.cpp Mon Apr 13 20:38:46 2009 -0700
@@ -9,12 +9,6 @@
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
@@ -31,14 +25,6 @@
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;
-}
-
// Simplex hash
template<class V, class T>
size_t hash_simplex(const Simplex<V,T>& s)
@@ -61,19 +47,6 @@
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
@@ -81,14 +54,12 @@
{
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))
@@ -97,7 +68,9 @@
.def("__eq__", &eq_simplex<Vertex, Data>)
;
+ class_<SimplexObject>("SimplexObject")
+ .def("__getattribute__", &SimplexObject::getattribute)
+ ;
+
def("vertex_cmp", &vertex_comparison<Vertex, Data>);
- def("data_cmp", &data_comparison<Vertex, Data>);
- def("data_dim_cmp", &data_dimension_comparison<Vertex, Data>);
}
--- a/bindings/python/static-persistence.cpp Sat Apr 11 10:29:53 2009 -0700
+++ b/bindings/python/static-persistence.cpp Mon Apr 13 20:38:46 2009 -0700
@@ -13,11 +13,6 @@
return p;
}
-void pair_simplices(SPersistence& p)
-{
- p.pair_simplices();
-}
-
void export_static_persistence()
{
class_<SPersistenceNode>("StaticPersistenceNode")
@@ -28,9 +23,7 @@
class_<SPersistence>("StaticPersistence", no_init)
.def("__init__", make_constructor(&init_from_filtration))
-
- .def("pair_simplices", &pair_simplices)
-
+ .def("pair_simplices", (void (SPersistence::*)()) &SPersistence::pair_simplices)
.def("__iter__", range(&SPersistence::begin, &SPersistence::end))
.def("__len__", &SPersistence::size)
;
--- a/include/topology/simplex.hpp Sat Apr 11 10:29:53 2009 -0700
+++ b/include/topology/simplex.hpp Mon Apr 13 20:38:46 2009 -0700
@@ -103,12 +103,13 @@
operator<<(std::ostream& out) const
{
typename VertexContainer::const_iterator cur = vertices().begin();
- out << *cur;
+ out << "<" << *cur;
for (++cur; cur != vertices().end(); ++cur)
{
out << ", " << *cur;
}
- out << " [" << data() << "] ";
+ out << ">";
+ // out << " [" << data() << "] ";
return out;
}