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  return true;
134  }
135 
137 
138  private:
139  /* \brief Adds recursively all the faces of a certain dimension dim witnessed by the same witness.
140  * Iterator is needed to know until how far we can take landmarks to form simplexes.
141  * simplex is the prefix of the simplexes to insert.
142  * The output value indicates if the witness rests active or not.
143  */
144  template < typename SimplicialComplexForWitness >
145  bool add_all_faces_of_dimension(int dim,
146  double alpha2,
147  double norelax_dist2,
148  typename ActiveWitness::iterator curr_l,
149  std::vector<Landmark_id>& simplex,
151  typename ActiveWitness::iterator end) const {
152  if (curr_l == end)
153  return false;
154  bool will_be_active = false;
155  typename ActiveWitness::iterator l_it = curr_l;
156  if (dim > 0) {
157  for (; l_it != end && l_it->second - alpha2 <= norelax_dist2; ++l_it) {
158  simplex.push_back(l_it->first);
159  if (sc.find(simplex) != sc.null_simplex()) {
160  typename ActiveWitness::iterator next_it = l_it;
161  will_be_active = add_all_faces_of_dimension(dim-1,
162  alpha2,
163  norelax_dist2,
164  ++next_it,
165  simplex,
166  sc,
167  end) || will_be_active;
168  }
169  assert(!simplex.empty());
170  simplex.pop_back();
171  // If norelax_dist is infinity, change to first omitted distance
172  if (l_it->second <= norelax_dist2)
173  norelax_dist2 = l_it->second;
174  }
175  } else if (dim == 0) {
176  for (; l_it != end && l_it->second - alpha2 <= norelax_dist2; ++l_it) {
177  simplex.push_back(l_it->first);
178  double filtration_value = 0;
179  // if norelax_dist is infinite, relaxation is 0.
180  if (l_it->second > norelax_dist2)
181  filtration_value = l_it->second - norelax_dist2;
182  if (all_faces_in(simplex, &filtration_value, sc)) {
183  will_be_active = true;
184  sc.insert_simplex(simplex, filtration_value);
185  }
186  assert(!simplex.empty());
187  simplex.pop_back();
188  // If norelax_dist is infinity, change to first omitted distance
189  if (l_it->second < norelax_dist2)
190  norelax_dist2 = l_it->second;
191  }
192  }
193  return will_be_active;
194  }
195 };
196 
197 } // namespace witness_complex
198 
199 } // namespace Gudhi
200 
201 #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...
GUDHI  Version 2.1.0  - C++ library for Topological Data Analysis (TDA) and Higher Dimensional Geometry Understanding.  - Copyright : GPL v3 Generated on Wed Jan 31 2018 09:40:55 for GUDHI by Doxygen 1.8.11