examples/rips/rips.cpp
author Dmitriy Morozov <dmitriy@mrzv.org>
Mon Jul 25 23:21:29 2011 -0700 (6 months ago)
branchdev
changeset 244 66235db8d8b7
parent 1250a2c2283e4a8
permissions -rw-r--r--
Added cohomology/candidates counter to i/t/cohomology-persistence.hpp
     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
     7 
     8 #include <fstream>
     9 #include <boost/archive/binary_oarchive.hpp>
    10 #include <boost/serialization/map.hpp>
    11 
    12 // Trivial example of size() points on a line with integer coordinates
    13 struct Distances
    14 {
    15     typedef         int             IndexType;
    16     typedef         double          DistanceType;
    17 
    18     DistanceType    operator()(IndexType a, IndexType b) const      { return std::abs(a - b); }
    19 
    20     size_t          size() const                                    { return 2000; }
    21     IndexType       begin() const                                   { return 0; }
    22     IndexType       end() const                                     { return size(); }
    23 };
    24 
    25 //typedef         Rips<ExplicitDistances<Distances> >                   Generator;
    26 typedef         Rips<Distances>                                         Generator;
    27 typedef         Generator::Simplex                                      Smplx;
    28 typedef         Filtration<Smplx>                                       Fltr;
    29 typedef         StaticPersistence<>                                     Persistence;
    30 // typedef         DynamicPersistenceChains<>                              Persistence;
    31 typedef         PersistenceDiagram<>                                    PDgm;
    32 
    33 
    34 int main(int argc, char* argv[])
    35 {
    36 #ifdef LOGGING
    37 	rlog::RLogInit(argc, argv);
    38 
    39 	stdoutLog.subscribeTo( RLOG_CHANNEL("error") );
    40 	stdoutLog.subscribeTo( RLOG_CHANNEL("info") );
    41 	//stdoutLog.subscribeTo( RLOG_CHANNEL("rips/info") );
    42 	//stdoutLog.subscribeTo( RLOG_CHANNEL("rips/debug") );
    43 #endif
    44 
    45     Distances distances;
    46     
    47     // Storing ExplicitDistances speeds up the computation (at the price of memory)
    48     //ExplicitDistances<Distances> explicit_distances(distances);
    49 
    50     Generator               rips(distances);
    51     Generator::Evaluator    size(distances);
    52     Fltr                    f;
    53     
    54     // Generate 2-skeleton of the Rips complex for epsilon = 50
    55     rips.generate(2, 10, make_push_back_functor(f));
    56     rInfo("Generated complex of size: %d",  f.size());
    57 
    58     // Generate filtration with respect to distance and compute its persistence
    59     f.sort(Generator::Comparison(distances));
    60     Persistence p(f);
    61     p.pair_simplices();
    62     rInfo("Simplices paired");
    63 
    64     Persistence::SimplexMap<Fltr>   m = p.make_simplex_map(f);
    65 
    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(m, size), 
    70                   evaluate_through_map(m, Smplx::DimensionExtractor()));
    71 
    72     // Serialize the diagrams to a file
    73     std::ofstream ofs("rips-diagrams");
    74     boost::archive::binary_oarchive oa(ofs);
    75     oa << dgms;
    76 
    77     // Output cycles
    78     for (Persistence::iterator cur = p.begin(); cur != p.end(); ++cur)
    79     {
    80         const Persistence::Cycle& cycle = cur->cycle;
    81 
    82         if (!cur->sign())        // only negative simplices have non-empty cycles
    83         {
    84             Persistence::OrderIndex birth = cur->pair;      // the cycle that cur killed was born when we added birth (another simplex)
    85 
    86             const Smplx& b = m[birth];
    87             const Smplx& d = m[cur];
    88             
    89             if (b.dimension() != 1) continue;
    90             std::cout << "Pair: (" << size(b) << ", " << size(d) << ")" << std::endl;
    91         } else if (cur->unpaired())    // positive could be unpaired
    92         {
    93             const Smplx& b = m[cur];
    94             if (b.dimension() != 1) continue;
    95             
    96             std::cout << "Unpaired birth: " << size(b) << std::endl;
    97             // cycle = cur->chain;
    98         }
    99 
   100         // Iterate over the cycle
   101         for (Persistence::Cycle::const_iterator si =  cycle.begin(); si != cycle.end(); ++si)
   102         {
   103             const Smplx& s = m[*si];
   104             //std::cout << s.dimension() << std::endl;
   105             const Smplx::VertexContainer& vertices = s.vertices();          // std::vector<Vertex> where Vertex = Distances::IndexType
   106             AssertMsg(vertices.size() == s.dimension() + 1, "dimension of a simplex is one less than the number of its vertices");
   107             std::cout << vertices[0] << " " << vertices[1] << std::endl;
   108         }
   109     }
   110 }