Changed implementation of WeightedRips to store simplex values (max distance between simplices' vertices) as an invisible layer on top of each simplex object, so that the data() field of WeightedRips has been freed for use by the users again.
#ifndef __COHOMOLOGY_PERSISTENCE_H__
#define __COHOMOLOGY_PERSISTENCE_H__
#if DEBUG_CONTAINERS
#include <debug/list>
#include <debug/vector>
namespace s = std::__debug;
#warning "Using debug/list and debug/vector in CohomologyPersistence"
#else
#include <list>
#include <vector>
namespace s = std;
#endif
#include <vector>
#include <list>
#include <utility>
#include <topology/field-arithmetic.h>
#include "utilities/types.h"
#include <boost/optional.hpp>
#include <boost/intrusive/list.hpp>
namespace bi = boost::intrusive;
template<class BirthInfo_, class SimplexData_ = Empty<>, class Field_ = ZpField>
class CohomologyPersistence
{
public:
typedef BirthInfo_ BirthInfo;
typedef SimplexData_ SimplexData;
typedef Field_ Field;
typedef typename Field::Element FieldElement;
CohomologyPersistence(const Field& field = Field()):
field_(field) {}
// An entry in a cocycle column
struct SNode; // members: si, coefficient, ci
typedef s::vector<SNode> ZColumn;
typedef bi::list<SNode, bi::constant_time_size<false> > ZRow;
class CompareSNode;
struct SHead; // members: row, order
typedef s::list<SHead> Simplices;
typedef typename Simplices::iterator SimplexIndex;
struct Cocycle; // members: zcolumn, birth, order
typedef s::list<Cocycle> Cocycles;
typedef typename Cocycles::iterator CocycleIndex;
typedef std::pair<CocycleIndex, FieldElement> CocycleCoefficientPair;
typedef boost::optional<BirthInfo> Death;
typedef std::pair<SimplexIndex, Death> IndexDeathPair;
// 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());
void show_cocycles() const;
CocycleIndex begin() { return cocycles_.begin(); }
CocycleIndex end() { return cocycles_.end(); }
private:
void add_cocycle(CocycleCoefficientPair& z1, CocycleCoefficientPair& z2);
private:
Simplices simplices_;
Cocycles cocycles_;
Field field_;
};
// Simplex representation
template<class BirthInfo_, class SimplexData_, class Field_>
struct CohomologyPersistence<BirthInfo_, SimplexData_, Field_>::SHead: public SimplexData
{
SHead(const SHead& other):
SimplexData(other), order(other.order) {} // don't copy row since we can't
SHead(const SimplexData& sd, unsigned o):
SimplexData(sd), order(o) {}
// intrusive list corresponding to row of s in Z^*, not ordered in any particular order
ZRow row;
unsigned order;
};
// An entry in a cocycle column; it's also an element in an intrusive list, hence the list_base_hook<>
typedef bi::list_base_hook<bi::link_mode<bi::auto_unlink> > auto_unlink_hook;
template<class BirthInfo_, class SimplexData_, class Field_>
struct CohomologyPersistence<BirthInfo_, SimplexData_, Field_>::SNode: public auto_unlink_hook
{
SNode(const SNode& other):
si(other.si), coefficient(other.coefficient),
ci(other.ci) {}
SNode(SimplexIndex sidx, FieldElement coef, CocycleIndex cidx):
si(sidx), coefficient(coef), ci(cidx) {}
SimplexIndex si;
FieldElement coefficient;
CocycleIndex ci; // TODO: is there no way to get rid of this overhead?
void unlink() { auto_unlink_hook::unlink(); }
};
template<class BirthInfo_, class SimplexData_, class Field_>
struct CohomologyPersistence<BirthInfo_, SimplexData_, Field_>::Cocycle
{
Cocycle(const BirthInfo& b, unsigned o):
birth(b), order(o) {}
ZColumn zcolumn;
BirthInfo birth;
unsigned order;
bool operator<(const Cocycle& other) const { return order > other.order; }
bool operator==(const Cocycle& other) const { return order == other.order; }
};
#include "cohomology-persistence.hpp"
#endif // __COHOMOLOGY_PERSISTENCE_H__