Witness_complex.h
1 /* This file is part of the Gudhi Library. The Gudhi library
2  * (Geometric Understanding in Higher Dimensions) is a generic C++
3  * library for computational topology.
4  *
5  * Author(s): Siargey Kachanovich
6  *
7  * Copyright (C) 2015 INRIA (France)
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef WITNESS_COMPLEX_H_
24 #define WITNESS_COMPLEX_H_
25 
26 #include <gudhi/Active_witness/Active_witness.h>
27 #include <gudhi/Witness_complex/all_faces_in.h>
28 
29 #include <utility>
30 #include <vector>
31 #include <list>
32 #include <limits>
33 
34 namespace Gudhi {
35 
36 namespace witness_complex {
37 
49 template< class Nearest_landmark_table_ >
51  private:
52  typedef typename Nearest_landmark_table_::value_type Nearest_landmark_range;
53  typedef std::size_t Witness_id;
54  typedef std::size_t Landmark_id;
55  typedef std::pair<Landmark_id, double> Id_distance_pair;
56  typedef Active_witness<Id_distance_pair, Nearest_landmark_range> ActiveWitness;
57  typedef std::list< ActiveWitness > ActiveWitnessList;
58  typedef std::vector< Landmark_id > typeVectorVertex;
59  typedef std::vector<Nearest_landmark_range> Nearest_landmark_table_internal;
60  typedef Landmark_id Vertex_handle;
61 
62  protected:
63  Nearest_landmark_table_internal nearest_landmark_table_;
64 
65  public:
67  /* @name Constructor
68  */
69 
71 
72  Witness_complex() {
73  }
74 
84  Witness_complex(Nearest_landmark_table_ const & nearest_landmark_table)
85  : nearest_landmark_table_(std::begin(nearest_landmark_table), std::end(nearest_landmark_table)) {
86  }
87 
97  template < typename SimplicialComplexForWitness >
99  double max_alpha_square,
100  std::size_t limit_dimension = std::numeric_limits<std::size_t>::max()) const {
101  if (complex.num_vertices() > 0) {
102  std::cerr << "Witness complex cannot create complex - complex is not empty.\n";
103  return false;
104  }
105  if (max_alpha_square < 0) {
106  std::cerr << "Witness complex cannot create complex - squared relaxation parameter must be non-negative.\n";
107  return false;
108  }
109  ActiveWitnessList active_witnesses;
110  Landmark_id k = 0; /* current dimension in iterative construction */
111  for (auto w : nearest_landmark_table_)
112  active_witnesses.push_back(ActiveWitness(w));
113  while (!active_witnesses.empty() && k <= limit_dimension) {
114  typename ActiveWitnessList::iterator aw_it = active_witnesses.begin();
115  std::vector<Landmark_id> simplex;
116  simplex.reserve(k+1);
117  while (aw_it != active_witnesses.end()) {
118  bool ok = add_all_faces_of_dimension(k,
119  max_alpha_square,
120  std::numeric_limits<double>::infinity(),
121  aw_it->begin(),
122  simplex,
123  complex,
124  aw_it->end());
125  assert(simplex.empty());
126  if (!ok)
127  active_witnesses.erase(aw_it++); // First increase the iterator and then erase the previous element
128  else
129  aw_it++;
130  }
131  k++;
132  }
133  complex.set_dimension(k-1);
134  return true;
135  }
136 
138 
139  private:
140  /* \brief Adds recursively all the faces of a certain dimension dim witnessed by the same witness.
141  * Iterator is needed to know until how far we can take landmarks to form simplexes.
142  * simplex is the prefix of the simplexes to insert.
143  * The output value indicates if the witness rests active or not.
144  */
145  template < typename SimplicialComplexForWitness >
146  bool add_all_faces_of_dimension(int dim,
147  double alpha2,
148  double norelax_dist2,
149  typename ActiveWitness::iterator curr_l,
150  std::vector<Landmark_id>& simplex,
152  typename ActiveWitness::iterator end) const {
153  if (curr_l == end)
154  return false;
155  bool will_be_active = false;
156  typename ActiveWitness::iterator l_it = curr_l;
157  if (dim > 0) {
158  for (; l_it != end && l_it->second - alpha2 <= norelax_dist2; ++l_it) {
159  simplex.push_back(l_it->first);
160  if (sc.find(simplex) != sc.null_simplex()) {
161  typename ActiveWitness::iterator next_it = l_it;
162  will_be_active = add_all_faces_of_dimension(dim-1,
163  alpha2,
164  norelax_dist2,
165  ++next_it,
166  simplex,
167  sc,
168  end) || will_be_active;
169  }
170  assert(!simplex.empty());
171  simplex.pop_back();
172  // If norelax_dist is infinity, change to first omitted distance
173  if (l_it->second <= norelax_dist2)
174  norelax_dist2 = l_it->second;
175  }
176  } else if (dim == 0) {
177  for (; l_it != end && l_it->second - alpha2 <= norelax_dist2; ++l_it) {
178  simplex.push_back(l_it->first);
179  double filtration_value = 0;
180  // if norelax_dist is infinite, relaxation is 0.
181  if (l_it->second > norelax_dist2)
182  filtration_value = l_it->second - norelax_dist2;
183  if (all_faces_in(simplex, &filtration_value, sc)) {
184  will_be_active = true;
185  sc.insert_simplex(simplex, filtration_value);
186  }
187  assert(!simplex.empty());
188  simplex.pop_back();
189  // If norelax_dist is infinity, change to first omitted distance
190  if (l_it->second < norelax_dist2)
191  norelax_dist2 = l_it->second;
192  }
193  }
194  return will_be_active;
195  }
196 };
197 
198 } // namespace witness_complex
199 
200 } // namespace Gudhi
201 
202 #endif // WITNESS_COMPLEX_H_
The concept SimplicialComplexForWitness describes the requirements for a type to implement a simplici...
Definition: SimplicialComplexForWitness.h:34
Simplex_handle null_simplex()
Returns a Simplex_hanlde that is different from all simplex handles of the simplices.
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 &#39;max_alpha_square&#39; in a simplicial complex data stru...
Definition: Witness_complex.h:98
Definition: SimplicialComplexForAlpha.h:26
Witness_complex(Nearest_landmark_table_ const &nearest_landmark_table)
Initializes member variables before constructing simplicial complex.
Definition: Witness_complex.h:84
Simplex_handle find(Input_vertex_range const &vertex_range)
Finds a simplex with vertices given by a range.
Constructs (weak) witness complex for a given table of nearest landmarks with respect to witnesses...
Definition: Witness_complex.h:50
Insertion_result_type insert_simplex(Input_vertex_range const &vertex_range, Filtration_value filtration)
Inserts a simplex with vertices from a given range &#39;vertex_range&#39; in the simplicial complex...
void set_dimension(int dimension)
Sets the dimension of the simplicial complex to &#39;dimension&#39;.
GUDHI  Version 2.0.1  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding. Generated on Mon Oct 2 2017 10:20:49 for GUDHI by doxygen 1.8.11