Added image persistence functionality to CohomologyPersistence dev
authorDmitriy Morozov <dmitriy@mrzv.org>
Wed, 28 Oct 2009 14:38:36 -0700
branchdev
changeset 172 a6605dc232f2
parent 171 a172b960aaaa
child 173 5fd3f43e6fbf
Added image persistence functionality to CohomologyPersistence
bindings/python/cohomology-persistence.cpp
doc/python/cohomology-persistence.rst
include/topology/cohomology-persistence.h
include/topology/cohomology-persistence.hpp
--- a/bindings/python/cohomology-persistence.cpp	Fri Oct 23 11:51:23 2009 -0700
+++ b/bindings/python/cohomology-persistence.cpp	Wed Oct 28 14:38:36 2009 -0700
@@ -40,6 +40,16 @@
     return bp::make_tuple(i,d);
 }
 
+bp::tuple                                   chp_add_store_image(dp::CohomPersistence& chp, bp::object bdry, dp::BirthID birth, bool store, bool image)
+{
+    dp::CohomPersistence::SimplexIndex      i;
+    dp::CohomPersistence::Death             d;
+    boost::tie(i,d)                                 = chp.add(bp::stl_input_iterator<dp::CohomPersistence::SimplexIndex>(bdry),
+                                                              bp::stl_input_iterator<dp::CohomPersistence::SimplexIndex>(),
+                                                              birth, store, dp::CohomPersistence::SimplexData(), image); 
+    return bp::make_tuple(i,d);
+}
+
 dp::CohomPersistence::ZColumn::const_iterator     
 cocycle_zcolumn_begin(dp::CohomPersistence::Cocycle& ccl)                   
 { return ccl.zcolumn.begin(); }
@@ -72,6 +82,7 @@
         .def("__init__",        bp::make_constructor(&init_from_prime))
         .def("add",             &chp_add)
         .def("add",             &chp_add_store)
+        .def("add",             &chp_add_store_image)
         
         .def("__iter__",        bp::range(&dp::CohomPersistence::begin, &dp::CohomPersistence::end))
     ;
--- a/doc/python/cohomology-persistence.rst	Fri Oct 23 11:51:23 2009 -0700
+++ b/doc/python/cohomology-persistence.rst	Wed Oct 28 14:38:36 2009 -0700
@@ -11,7 +11,7 @@
         this point on all the computation will be performed with coefficients
         coming from :math:`\mathbb{Z}/prime \mathbb{Z}`.
 
-    .. method:: add(boundary, birth, [store = True])
+    .. method:: add(boundary, birth, [store = True, [image = True]])
         
         Adds a simplex with the given `boundary` to the complex, i.e. 
         :math:`K_{i+1} = K_i \cup \sigma` and `boundary` = :math:`\partial \sigma`.
@@ -23,6 +23,13 @@
         classes of the dimension equal to the maximum-dimensional simplices of
         the complex since such classes will never die.
 
+        The `image` parameter allows one to work with a case of a space 
+        :math:`L \subseteq K` where the filtration of :math:`K` induces a
+        filtration of :math:`L`. In this case, one may want to compute **image
+        persistence** (i.e. the persistence of the sequences of the images given
+        by the inclusion of :math:`L` in :math:`K`). `image` indicates whether
+        the simplex added belongs to :math:`L` or not.
+
         :returns: a pair (`i`, `d`). The first element is the index `i`. 
                   It is the internal representation of the newly added simplex,
                   and should be used later for removal or when constructing the
--- a/include/topology/cohomology-persistence.h	Fri Oct 23 11:51:23 2009 -0700
+++ b/include/topology/cohomology-persistence.h	Wed Oct 28 14:38:36 2009 -0700
@@ -36,7 +36,7 @@
 
 
                             CohomologyPersistence(const Field& field = Field()):
-                                field_(field)                                           {}
+                                field_(field), image_begin_(cocycles_.end())            {}
 
 
         // An entry in a cocycle column
@@ -60,7 +60,7 @@
         // return either a SimplexIndex or a Death
         // BI = BoundaryIterator; it should dereference to a SimplexIndex
         template<class BI>
-        IndexDeathPair      add(BI begin, BI end, BirthInfo b, bool store = true, const SimplexData& sd = SimplexData());
+        IndexDeathPair      add(BI begin, BI end, BirthInfo b, bool store = true, const SimplexData& sd = SimplexData(), bool image = true);
 
         void                show_cocycles() const;
         CocycleIndex        begin()                                                     { return cocycles_.begin(); }
@@ -72,6 +72,7 @@
     private:
         Simplices           simplices_;
         Cocycles            cocycles_;
+        CocycleIndex        image_begin_;
         Field               field_;
 };
         
@@ -117,7 +118,7 @@
 
     ZColumn         zcolumn;
     BirthInfo       birth;
-    unsigned        order;
+    signed          order;
 
     bool            operator<(const Cocycle& other) const                       { return order > other.order; }
     bool            operator==(const Cocycle& other) const                      { return order == other.order; }
--- a/include/topology/cohomology-persistence.hpp	Fri Oct 23 11:51:23 2009 -0700
+++ b/include/topology/cohomology-persistence.hpp	Wed Oct 28 14:38:36 2009 -0700
@@ -1,6 +1,7 @@
 #include <boost/utility.hpp>
 #include <queue>
 #include <vector>
+#include <limits>
 
 #include <utilities/log.h>
 #include <utilities/indirect.h>
@@ -20,7 +21,7 @@
 template<class BI>
 typename CohomologyPersistence<BirthInfo, SimplexData, Field>::IndexDeathPair
 CohomologyPersistence<BirthInfo, SimplexData, Field>::
-add(BI begin, BI end, BirthInfo birth, bool store, const SimplexData& sd)
+add(BI begin, BI end, BirthInfo birth, bool store, const SimplexData& sd, bool image)
 {
     // Create simplex representation
     simplices_.push_back(SHead(sd, simplices_.empty() ? 0 : (simplices_.back().order + 1)));
@@ -73,21 +74,40 @@
     // Birth
     if (candidates.empty())
     {
+        // rLog(rlCohomology, "  Birth occurred");
         if (!store)
         {
             simplices_.pop_back();
             return std::make_pair(simplices_.begin(), Death());         // TODO: shouldn't return front
         }
         
-        unsigned order = cocycles_.empty() ? 0 : cocycles_.front().order + 1;
-        cocycles_.push_front(Cocycle(birth, order));
+        signed order = 0;
+        if (image)
+            if (image_begin_ == cocycles_.end())
+                order = std::numeric_limits<signed>::min();
+            else
+                order = image_begin_->order + 1;
+        else
+            if (!cocycles_.empty() && cocycles_.front().order >= 0)     // we have something outside the image
+                order = cocycles_.front().order + 1;
+
+        CocycleIndex nw;
+        if (image)
+        {
+            image_begin_ = cocycles_.insert(image_begin_, Cocycle(birth, order));
+            nw = image_begin_;
+        } else
+        {
+            cocycles_.push_front(Cocycle(birth, order));
+            nw = cocycles_.begin();
+        }
         
-        rLog(rlCohomology,  "Birth: %d", cocycles_.front().order);
+        rLog(rlCohomology,  "Birth: %d", nw->order);
 
         // set up the cocycle
-        ZColumn& cocycle = cocycles_.front().zcolumn;
-        cocycle.push_back(SNode(si, field_.id(), cocycles_.begin()));
-        si->row.push_back(cocycles_.front().zcolumn.front());
+        ZColumn& cocycle = nw->zcolumn;
+        cocycle.push_back(SNode(si, field_.id(), nw));
+        si->row.push_back(cocycle.front());
         rLog(rlCohomology,  "  Cocyle: %d", si->order);
 
         return std::make_pair(si, Death());
@@ -105,6 +125,12 @@
 
     CocycleCoefficientPair& z   = candidates.front();
     Death d                     = z.first->birth;
+    rLog(rlCohomology, "  Order: %d", z.first->order);
+    if (z.first->order >= 0)    // if death outside image
+        d = Death();            // no death occurs outside the image
+    else
+        if (z.first == image_begin_)
+            ++image_begin_;
 
     // add z to everything else in candidates
     for (typename Candidates::iterator cur  = boost::next(candidates.begin());