Witness_complex.h
1 /* This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
2  * See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
3  * Author(s): Siargey Kachanovich
4  *
5  * Copyright (C) 2015 Inria
6  *
7  * Modification(s):
8  * - YYYY/MM Author: Description of the modification
9  */
10 
11 #ifndef WITNESS_COMPLEX_H_
12 #define WITNESS_COMPLEX_H_
13 
14 #include <gudhi/Active_witness/Active_witness.h>
15 #include <gudhi/Witness_complex/all_faces_in.h>
16 
17 #include <utility>
18 #include <vector>
19 #include <list>
20 #include <limits>
21 
22 namespace Gudhi {
23 
24 namespace witness_complex {
25 
37 template< class Nearest_landmark_table_ >
39  private:
40  typedef typename Nearest_landmark_table_::value_type Nearest_landmark_range;
41  typedef std::size_t Witness_id;
42  typedef std::size_t Landmark_id;
43  typedef std::pair<Landmark_id, double> Id_distance_pair;
45  typedef std::list< ActiveWitness > ActiveWitnessList;
46  typedef std::vector< Landmark_id > typeVectorVertex;
47  typedef std::vector<Nearest_landmark_range> Nearest_landmark_table_internal;
48  typedef Landmark_id Vertex_handle;
49 
50  protected:
51  Nearest_landmark_table_internal nearest_landmark_table_;
52 
53  public:
55  /* @name Constructor
56  */
57 
59 
60  Witness_complex() {
61  }
62 
75  Witness_complex(Nearest_landmark_table_ const & nearest_landmark_table)
76  : nearest_landmark_table_(std::begin(nearest_landmark_table), std::end(nearest_landmark_table)) {
77  }
78 
88  template < typename SimplicialComplexForWitness >
90  double max_alpha_square,
91  std::size_t limit_dimension = std::numeric_limits<std::size_t>::max()) const {
92  if (complex.num_vertices() > 0) {
93  std::cerr << "Witness complex cannot create complex - complex is not empty.\n";
94  return false;
95  }
96  if (max_alpha_square < 0) {
97  std::cerr << "Witness complex cannot create complex - squared relaxation parameter must be non-negative.\n";
98  return false;
99  }
100  ActiveWitnessList active_witnesses;
101  Landmark_id k = 0; /* current dimension in iterative construction */
102  for (auto&& w : nearest_landmark_table_)
103  active_witnesses.emplace_back(w);
104  while (!active_witnesses.empty() && k <= limit_dimension) {
105  typename ActiveWitnessList::iterator aw_it = active_witnesses.begin();
106  std::vector<Landmark_id> simplex;
107  simplex.reserve(k+1);
108  while (aw_it != active_witnesses.end()) {
109  bool ok = add_all_faces_of_dimension(k,
110  max_alpha_square,
111  std::numeric_limits<double>::infinity(),
112  aw_it->begin(),
113  simplex,
114  complex,
115  aw_it->end());
116  assert(simplex.empty());
117  if (!ok)
118  active_witnesses.erase(aw_it++); // First increase the iterator and then erase the previous element
119  else
120  aw_it++;
121  }
122  k++;
123  }
124  return true;
125  }
126 
128 
129  private:
135  template < typename SimplicialComplexForWitness >
136  bool add_all_faces_of_dimension(int dim,
137  double alpha2,
138  double norelax_dist2,
139  typename ActiveWitness::iterator curr_l,
140  std::vector<Landmark_id>& simplex,
142  typename ActiveWitness::iterator end) const {
143  if (curr_l == end)
144  return false;
145  bool will_be_active = false;
146  typename ActiveWitness::iterator l_it = curr_l;
147  if (dim > 0) {
148  for (; l_it != end && l_it->second - alpha2 <= norelax_dist2; ++l_it) {
149  simplex.push_back(l_it->first);
150  if (sc.find(simplex) != sc.null_simplex()) {
151  typename ActiveWitness::iterator next_it = l_it;
152  will_be_active = add_all_faces_of_dimension(dim-1,
153  alpha2,
154  norelax_dist2,
155  ++next_it,
156  simplex,
157  sc,
158  end) || will_be_active;
159  }
160  assert(!simplex.empty());
161  simplex.pop_back();
162  // If norelax_dist is infinity, change to first omitted distance
163  if (l_it->second <= norelax_dist2)
164  norelax_dist2 = l_it->second;
165  }
166  } else if (dim == 0) {
167  for (; l_it != end && l_it->second - alpha2 <= norelax_dist2; ++l_it) {
168  simplex.push_back(l_it->first);
169  double filtration_value = 0;
170  // if norelax_dist is infinite, relaxation is 0.
171  if (l_it->second > norelax_dist2)
172  filtration_value = l_it->second - norelax_dist2;
173  if (all_faces_in(simplex, &filtration_value, sc)) {
174  will_be_active = true;
175  sc.insert_simplex(simplex, filtration_value);
176  }
177  assert(!simplex.empty());
178  simplex.pop_back();
179  // If norelax_dist is infinity, change to first omitted distance
180  if (l_it->second < norelax_dist2)
181  norelax_dist2 = l_it->second;
182  }
183  }
184  return will_be_active;
185  }
186 };
187 
188 } // namespace witness_complex
189 
190 } // namespace Gudhi
191 
192 #endif // WITNESS_COMPLEX_H_
Class representing a list of nearest neighbors to a given witness.
Definition: Active_witness.h:27
Constructs (weak) witness complex for a given table of nearest landmarks with respect to witnesses.
Definition: Witness_complex.h:38
bool create_complex(SimplicialComplexForWitness &complex, double max_alpha_square, std::size_t limit_dimension=std::numeric_limits< std::size_t >::max()) const
Outputs the (weak) witness complex of relaxation 'max_alpha_square' in a simplicial complex data stru...
Definition: Witness_complex.h:89
Witness_complex(Nearest_landmark_table_ const &nearest_landmark_table)
Initializes member variables before constructing simplicial complex.
Definition: Witness_complex.h:75
Gudhi namespace.
Definition: SimplicialComplexForAlpha.h:14
The concept SimplicialComplexForWitness describes the requirements for a type to implement a simplici...
Definition: SimplicialComplexForWitness.h:22
Insertion_result_type insert_simplex(Input_vertex_range const &vertex_range, Filtration_value filtration)
Inserts a simplex with vertices from a given range 'vertex_range' in the simplicial complex....
Simplex_handle find(Input_vertex_range const &vertex_range)
Finds a simplex with vertices given by a range.
Simplex_handle null_simplex()
Returns a Simplex_hanlde that is different from all simplex handles of the simplices.