--- 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());