examples/rips/rips-pairwise.cpp
author Dmitriy Morozov <dmitriy@mrzv.org>
Wed Dec 16 15:39:06 2009 -0800 (2 years ago)
branchdev
changeset 179 d15c6d144645
parent 142ae2b1702c936
child 182451748b3c888
permissions -rw-r--r--
Resurrected vineyard code:
* Switched StaticPersistence + (serializable) Filtration to Boost.MultiIndex
* Updated DynamicPersistenceTrails to work with the new MultiIndex way
* Created LSVineyard class, and fixed the grid examples
     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 
     7 #include <geometry/l2distance.h>
     8 #include <geometry/distances.h>
     9 
    10 #include <utilities/containers.h>           // for BackInsertFunctor
    11 #include <utilities/timer.h>
    12 
    13 #include <vector>
    14 
    15 #include <boost/program_options.hpp>
    16 
    17 
    18 typedef         PairwiseDistances<PointContainer, L2Distance>           PairDistances;
    19 typedef         PairDistances::DistanceType                             DistanceType;
    20 typedef         PairDistances::IndexType                                Vertex;
    21 
    22 typedef         Rips<PairDistances>                                     Generator;
    23 typedef         Generator::Simplex                                      Smplx;
    24 typedef         Filtration<Smplx>                                       Fltr;
    25 // typedef         StaticPersistence<>                                     Persistence;
    26 typedef         DynamicPersistenceChains<>                              Persistence;
    27 typedef         PersistenceDiagram<>                                    PDgm;
    28 
    29 void            program_options(int argc, char* argv[], std::string& infilename, Dimension& skeleton, DistanceType& max_distance);
    30 
    31 int main(int argc, char* argv[])
    32 {
    33     Dimension               skeleton;
    34     DistanceType            max_distance;
    35     std::string             infilename;
    36 
    37     program_options(argc, argv, infilename, skeleton, max_distance);
    38 
    39     PointContainer          points;
    40     read_points(infilename, points);
    41 
    42     PairDistances           distances(points);
    43     Generator               rips(distances);
    44     Generator::Evaluator    size(distances);
    45     Fltr                    f;
    46     
    47     // Generate 2-skeleton of the Rips complex for epsilon = 50
    48     rips.generate(skeleton, max_distance, make_push_back_functor(f));
    49     std::cout << "# Generated complex of size: " << f.size() << std::endl;
    50 
    51     // Generate filtration with respect to distance and compute its persistence
    52     f.sort(Generator::Comparison(distances));
    53 
    54     Timer persistence_timer; persistence_timer.start();
    55     Persistence p(f);
    56     p.pair_simplices();
    57     persistence_timer.stop();
    58 
    59 #if 1
    60     // Output cycles
    61     Persistence::SimplexMap<Fltr>   m = p.make_simplex_map(f);
    62     for (Persistence::iterator cur = p.begin(); cur != p.end(); ++cur)
    63     {
    64         const Persistence::Cycle& cycle = cur->cycle;
    65 
    66         if (!cur->sign())        // only negative simplices have non-empty cycles
    67         {
    68             Persistence::OrderIndex birth = cur->pair;      // the cycle that cur killed was born when we added birth (another simplex)
    69 
    70             const Smplx& b = m[birth];
    71             const Smplx& d = m[cur];
    72             
    73             // if (b.dimension() != 1) continue;
    74             // std::cout << "Pair: (" << size(b) << ", " << size(d) << ")" << std::endl;
    75             if (b.dimension() >= skeleton) continue;
    76             std::cout << b.dimension() << " " << size(b) << " " << size(d) << std::endl;
    77         } else if (cur->unpaired())    // positive could be unpaired
    78         {
    79             const Smplx& b = m[cur];
    80             // if (b.dimension() != 1) continue;
    81             
    82             // std::cout << "Unpaired birth: " << size(b) << std::endl;
    83             // cycle = cur->chain;      // TODO
    84             if (b.dimension() >= skeleton) continue;
    85             std::cout << b.dimension() << " " << size(b) << " inf" << std::endl;
    86         }
    87 
    88         // Iterate over the cycle
    89         // for (Persistence::Cycle::const_iterator si =  cycle.begin();
    90         //                                                          si != cycle.end();     ++si)
    91         // {
    92         //     const Smplx& s = m[*si];
    93         //     //std::cout << s.dimension() << std::endl;
    94         //     const Smplx::VertexContainer& vertices = s.vertices();          // std::vector<Vertex> where Vertex = Distances::IndexType
    95         //     AssertMsg(vertices.size() == s.dimension() + 1, "dimension of a simplex is one less than the number of its vertices");
    96         //     std::cout << vertices[0] << " " << vertices[1] << std::endl;
    97         // }
    98     }
    99 #endif
   100     
   101     persistence_timer.check("# Persistence timer");
   102 }
   103 
   104 void        program_options(int argc, char* argv[], std::string& infilename, Dimension& skeleton, DistanceType& max_distance)
   105 {
   106     namespace po = boost::program_options;
   107 
   108     po::options_description     hidden("Hidden options");
   109     hidden.add_options()
   110         ("input-file",          po::value<std::string>(&infilename),        "Point set whose Rips zigzag we want to compute");
   111     
   112     po::options_description visible("Allowed options", 100);
   113     visible.add_options()
   114         ("help,h",                                                                                  "produce help message")
   115         ("skeleton-dimsnion,s", po::value<Dimension>(&skeleton)->default_value(2),                  "Dimension of the Rips complex we want to compute")
   116         ("max-distance,m",      po::value<DistanceType>(&max_distance)->default_value(Infinity),    "Maximum value for the Rips complex construction");
   117 
   118     po::positional_options_description pos;
   119     pos.add("input-file", 1);
   120     
   121     po::options_description all; all.add(visible).add(hidden);
   122 
   123     po::variables_map vm;
   124     po::store(po::command_line_parser(argc, argv).
   125                   options(all).positional(pos).run(), vm);
   126     po::notify(vm);
   127 
   128     if (vm.count("help") || !vm.count("input-file"))
   129     { 
   130         std::cout << "Usage: " << argv[0] << " [options] input-file" << std::endl;
   131         std::cout << visible << std::endl; 
   132         std::abort();
   133     }
   134 }