Loading...
Searching...
No Matches
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
22namespace Gudhi {
23
24namespace witness_complex {
25
37template< 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
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
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.