Changes in Python Bindings: dev
authorDmitriy Morozov <dmitriy@mrzv.org>
Mon, 13 Apr 2009 20:38:46 -0700
branchdev
changeset 127 406c6cc00b9c
parent 126 3c3e77ac43d2
child 128 a5fd0c2a1c88
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
bindings/python/dionysus/__init__.py
bindings/python/python-filtration.h
bindings/python/python-rips.h
bindings/python/python-simplex.h
bindings/python/rips.cpp
bindings/python/simplex.cpp
bindings/python/static-persistence.cpp
include/topology/simplex.hpp
--- 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;
 }