1 #include <topology/rips.h>
2 #include <topology/filtration.h>
3 #include <topology/static-persistence.h>
4 #include <topology/dynamic-persistence.h>
5 #include <topology/persistence-diagram.h>
6 #include <utilities/containers.h> // for BackInsertFunctor
9 #include <boost/archive/binary_oarchive.hpp>
10 #include <boost/serialization/map.hpp>
12 // Trivial example of size() points on a line with integer coordinates
15 typedef int IndexType;
16 typedef double DistanceType;
18 DistanceType operator()(IndexType a, IndexType b) const { return std::abs(a - b); } 20 size_t size() const { return 2000; } 21 IndexType begin() const { return 0; } 22 IndexType end() const { return size(); } 25 //typedef Rips<ExplicitDistances<Distances> > Generator;
26 typedef Rips<Distances> Generator;
27 typedef Generator::Simplex Smplx;
28 typedef std::vector<Smplx> SimplexVector;
29 typedef Filtration<SimplexVector, unsigned> Fltr;
30 //typedef StaticPersistence<> Persistence;
31 typedef DynamicPersistenceChains<> Persistence;
32 typedef PersistenceDiagram<> PDgm;
35 int main(int argc, char* argv[])
38 rlog::RLogInit(argc, argv);
40 stdoutLog.subscribeTo( RLOG_CHANNEL("error") ); 41 stdoutLog.subscribeTo( RLOG_CHANNEL("info") ); 42 //stdoutLog.subscribeTo( RLOG_CHANNEL("rips/info") ); 43 //stdoutLog.subscribeTo( RLOG_CHANNEL("rips/debug") ); 48 // Storing ExplicitDistances speeds up the computation (at the price of memory)
49 //ExplicitDistances<Distances> explicit_distances(distances);
51 Generator rips(distances);
52 Generator::Evaluator size(distances);
53 SimplexVector complex;
55 // Generate 2-skeleton of the Rips complex for epsilon = 50
56 rips.generate(2, 10, make_push_back_functor(complex));
57 std::sort(complex.begin(), complex.end(), Smplx::VertexComparison()); // unnecessary
58 rInfo("Generated complex of size: %d", complex.size()); 60 // Generate filtration with respect to distance and compute its persistence
61 Fltr f(complex.begin(), complex.end(), Generator::Comparison(distances));
64 rInfo("Simplices paired"); 66 // Record the persistence intervals in the persistence diagrams
67 std::map<Dimension, PDgm> dgms;
68 init_diagrams(dgms, p.begin(), p.end(),
69 evaluate_through_map(make_offset_map(p.begin(), f.begin()),
70 evaluate_through_filtration(f, size)),
71 evaluate_through_map(make_offset_map(p.begin(), f.begin()),
72 evaluate_through_filtration(f, Smplx::DimensionExtractor())));
74 // Serialize the diagrams to a file
75 std::ofstream ofs("rips-diagrams"); 76 boost::archive::binary_oarchive oa(ofs);
80 for (Persistence::OrderIndex cur = p.begin(); cur != p.end(); ++cur)
82 Persistence::Cycle& cycle = cur->cycle;
84 if (!cur->sign()) // only negative simplices have non-empty cycles
86 Persistence::OrderIndex birth = cur->pair; // the cycle that cur killed was born when we added birth (another simplex)
88 const Smplx& b = f.simplex(f.begin() + (birth - p.begin())); // eventually this will be encapsulated behind an interface
89 const Smplx& d = f.simplex(f.begin() + (cur - p.begin()));
91 if (b.dimension() != 1) continue;
92 std::cout << "Pair: (" << size(b) << ", " << size(d) << ")" << std::endl; 93 } else if (cur->pair == cur) // positive could be unpaired
95 const Smplx& b = f.simplex(f.begin() + (cur - p.begin()));
96 if (b.dimension() != 1) continue;
98 std::cout << "Unpaired birth: " << size(b) << std::endl;
102 // Iterate over the cycle
103 for (Persistence::Cycle::const_iterator si = cycle.begin();
104 si != cycle.end(); ++si)
106 const Smplx& s = f.simplex(f.begin() + (*si - p.begin()));
107 //std::cout << s.dimension() << std::endl;
108 const Smplx::VertexContainer& vertices = s.vertices(); // std::vector<Vertex> where Vertex = Distances::IndexType
109 AssertMsg(vertices.size() == s.dimension() + 1, "dimension of a simplex is one less than the number of its vertices");
110 std::cout << vertices[0] << " " << vertices[1] << std::endl;