11#ifndef SPARSE_RIPS_COMPLEX_H_ 
   12#define SPARSE_RIPS_COMPLEX_H_ 
   14#include <gudhi/Debug_utils.h> 
   16#include <gudhi/choose_n_farthest_points.h> 
   18#include <boost/graph/graph_traits.hpp> 
   19#include <boost/range/metafunctions.hpp> 
   20#include <boost/iterator/counting_iterator.hpp> 
   25namespace rips_complex {
 
   27template <
class Vertex_handle, 
class Filtration_value>
 
   29  typedef std::vector<Vertex_handle> VList;
 
   30  typedef std::vector<std::tuple<Vertex_handle, Vertex_handle, Filtration_value>> EList;
 
   31  typedef typename VList::const_iterator vertex_iterator;
 
   32  typedef boost::counting_iterator<std::size_t> edge_iterator;
 
   36template <
class Vertex_handle, 
class Filtration_value>
 
   37void add_vertex(
Vertex_handle v, Graph<Vertex_handle, Filtration_value>&g) { g.vlist.push_back(v); }
 
   38template <
class Vertex_handle, 
class Filtration_value>
 
   40template <
class Vertex_handle, 
class Filtration_value>
 
   41std::size_t num_vertices(Graph<Vertex_handle, Filtration_value> 
const&g) { 
return g.vlist.size(); }
 
   42template <
class Vertex_handle, 
class Filtration_value>
 
   43std::size_t num_edges(Graph<Vertex_handle, Filtration_value> 
const&g) { 
return g.elist.size(); }
 
   44template <class Vertex_handle, class Filtration_value, class Iter = typename Graph<Vertex_handle, Filtration_value>::vertex_iterator>
 
   46vertices(Graph<Vertex_handle, Filtration_value> 
const&g) {
 
   47  return { g.vlist.begin(), g.vlist.end() };
 
   49template <
class Vertex_handle, 
class Filtration_value>
 
   50std::pair<boost::counting_iterator<std::size_t>, boost::counting_iterator<std::size_t>>
 
   51edges(Graph<Vertex_handle, Filtration_value> 
const&g) {
 
   52  typedef boost::counting_iterator<std::size_t> I;
 
   53  return { I(0), I(g.elist.size()) };
 
   55template <
class Vertex_handle, 
class Filtration_value>
 
   56Vertex_handle source(std::size_t e, Graph<Vertex_handle, Filtration_value> 
const&g) { 
return std::get<0>(g.elist[e]); }
 
   57template <
class Vertex_handle, 
class Filtration_value>
 
   58Vertex_handle target(std::size_t e, Graph<Vertex_handle, Filtration_value> 
const&g) { 
return std::get<1>(g.elist[e]); }
 
   59template <
class Vertex_handle, 
class Filtration_value>
 
   61template <
class Vertex_handle, 
class Filtration_value>
 
   62Filtration_value get(edge_filtration_t, Graph<Vertex_handle, Filtration_value> 
const&g, std::size_t e) { 
return std::get<2>(g.elist[e]); }
 
   66template <
class Vertex_handle, 
class Filtration_value>
 
   67struct graph_traits<Gudhi::rips_complex::Graph<Vertex_handle, Filtration_value>> {
 
   68  typedef Gudhi::rips_complex::Graph<Vertex_handle, Filtration_value> G;
 
   69  struct traversal_category : vertex_list_graph_tag, edge_list_graph_tag {};
 
   71  typedef typename G::vertex_iterator vertex_iterator;
 
   72  typedef std::size_t vertices_size_type;
 
   73  typedef std::size_t edge_descriptor;
 
   74  typedef typename G::edge_iterator edge_iterator;
 
   75  typedef std::size_t edges_size_type;
 
   76  typedef directed_tag directed_category;
 
   77  typedef disallow_parallel_edge_tag edge_parallel_category;
 
   84namespace rips_complex {
 
  103template <
typename Filtration_value>
 
  107  typedef int Vertex_handle;
 
  108  typedef rips_complex::Graph<Vertex_handle, Filtration_value> Graph;
 
  120  template <
typename RandomAccessPo
intRange, 
typename Distance>
 
  122      : epsilon_(epsilon) {
 
  123    GUDHI_CHECK(epsilon > 0, 
"epsilon must be positive");
 
  124    auto dist_fun = [&](Vertex_handle i, Vertex_handle j) { 
return distance(points[i], points[j]); };
 
  127                                          std::back_inserter(sorted_points), std::back_inserter(params));
 
  128    compute_sparse_graph(dist_fun, epsilon, mini, maxi);
 
  141  template <
typename DistanceMatrix>
 
  144                            [&](Vertex_handle i, Vertex_handle j) { 
return (i==j) ? 0 : (i<j) ? distance_matrix[j][i] : distance_matrix[i][j]; },
 
  145                            epsilon, mini, maxi) {}
 
  157  template <
typename SimplicialComplexForRips>
 
  160                std::invalid_argument(
"Sparse_rips_complex::create_complex - simplicial complex is not empty"));
 
  167    const std::size_t n = num_vertices(graph_);
 
  168    std::vector<Filtration_value> lambda(max_v + 1);
 
  170    for(std::size_t i=0;i<n;++i)
 
  171      lambda[sorted_points[i]] = params[i];
 
  172    double cst = epsilon_ * (1 - epsilon_) / 2;
 
  174      auto filt = complex.filtration(sh);
 
  175      auto min_f = filt * cst;
 
  177        if(lambda[v] < min_f)
 
  187  template <
typename Distance>
 
  189    const auto& points = sorted_points; 
 
  190    std::size_t n = boost::size(points);
 
  191    double cst = epsilon * (1 - epsilon) / 2;
 
  193    for (std::size_t i = 0; i < n; ++i) {
 
  194      if ((params[i] < mini || params[i] <= 0) && i != 0) 
break;
 
  198      add_vertex(points[i], graph_);
 
  199      max_v = std::max(max_v, points[i]);
 
  201    n = num_vertices(graph_);
 
  206    for (std::size_t i = 0; i < n; ++i) {
 
  207      auto&& pi = points[i];
 
  212      for (std::size_t j = i + 1; j < n; ++j) {
 
  213        auto&& pj = points[j];
 
  214        auto d = dist(pi, pj);
 
  216        GUDHI_CHECK(lj <= li, 
"Bad furthest point sorting");
 
  220        if (d * epsilon <= 2 * lj)
 
  222        else if (d * epsilon > li + lj)
 
  225          alpha = (d - lj / epsilon) * 2;
 
  227          if (epsilon < 1 && alpha * cst > lj)
 
  232          add_edge(pi, pj, alpha, graph_);
 
  242  std::vector<Vertex_handle> sorted_points;
 
  244  std::vector<Filtration_value> params;
 
Sparse Rips complex data structure.
Definition: Sparse_rips_complex.h:104
Sparse_rips_complex(const RandomAccessPointRange &points, Distance distance, double const epsilon, Filtration_value const mini=-std::numeric_limits< Filtration_value >::infinity(), Filtration_value const maxi=std::numeric_limits< Filtration_value >::infinity())
Sparse_rips_complex constructor from a list of points.
Definition: Sparse_rips_complex.h:121
Sparse_rips_complex(const DistanceMatrix &distance_matrix, double const epsilon, Filtration_value const mini=-std::numeric_limits< Filtration_value >::infinity(), Filtration_value const maxi=std::numeric_limits< Filtration_value >::infinity())
Sparse_rips_complex constructor from a distance matrix.
Definition: Sparse_rips_complex.h:142
void create_complex(SimplicialComplexForRips &complex, int const dim_max)
Fills the simplicial complex with the sparse Rips graph and expands it with all the cliques,...
Definition: Sparse_rips_complex.h:158
Graph simplicial complex methods.
void choose_n_farthest_points(Distance dist, Point_range const &input_pts, std::size_t final_size, std::size_t starting_point, PointOutputIterator output_it, DistanceOutputIterator dist_it={})
Subsample by a greedy strategy of iteratively adding the farthest point from the current chosen point...
Definition: choose_n_farthest_points.h:69
Value type for a filtration function on a cell complex.
Definition: FiltrationValue.h:20
The concept SimplicialComplexForRips describes the requirements for a type to implement a simplicial ...
Definition: SimplicialComplexForRips.h:21
unspecified simplex_vertex_range(Simplex_handle sh)
Returns a range over the vertices of a simplex.
std::size_t num_vertices()
Returns the number of vertices in the simplicial complex.
unspecified Simplex_handle
Handle type to a simplex contained in the simplicial complex.
Definition: SimplicialComplexForRips.h:26
void expansion(int max_dim)
Expands the simplicial complex containing only its one skeleton until a given maximal dimension as ex...
void expansion_with_blockers(int max_dim, Blocker block_simplex)
Expands a simplicial complex containing only a graph. Simplices corresponding to cliques in the graph...
void insert_graph(const OneSkeletonGraph &skel_graph)
Inserts a given Gudhi::rips_complex::Rips_complex::OneSkeletonGraph in the simplicial complex.
Handle type for the vertices of a cell complex.
Definition: VertexHandle.h:15