summaryrefslogtreecommitdiff
path: root/src/Witness_complex
diff options
context:
space:
mode:
Diffstat (limited to 'src/Witness_complex')
-rw-r--r--src/Witness_complex/example/witness_complex_from_file.cpp7
-rw-r--r--src/Witness_complex/example/witness_complex_sphere.cpp6
-rw-r--r--src/Witness_complex/include/gudhi/Construct_closest_landmark_table.h6
-rw-r--r--src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h105
-rw-r--r--src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h96
-rw-r--r--src/Witness_complex/include/gudhi/Witness_complex.h2
-rw-r--r--src/Witness_complex/test/simple_witness_complex.cpp2
-rw-r--r--src/Witness_complex/test/witness_complex_points.cpp4
8 files changed, 217 insertions, 11 deletions
diff --git a/src/Witness_complex/example/witness_complex_from_file.cpp b/src/Witness_complex/example/witness_complex_from_file.cpp
index bb641b3c..59dd28e0 100644
--- a/src/Witness_complex/example/witness_complex_from_file.cpp
+++ b/src/Witness_complex/example/witness_complex_from_file.cpp
@@ -36,8 +36,9 @@
#include <string>
#include <vector>
-typedef std::vector< Vertex_handle > typeVectorVertex;
+typedef std::vector< int > typeVectorVertex;
typedef std::vector< std::vector <double> > Point_Vector;
+typedef Gudhi::Simplex_tree<> Simplex_tree;
int main(int argc, char * const argv[]) {
if (argc != 3) {
@@ -51,7 +52,7 @@ int main(int argc, char * const argv[]) {
clock_t start, end;
// Construct the Simplex Tree
- Gudhi::Simplex_tree<> simplex_tree;
+ Simplex_tree simplex_tree;
// Read the OFF file (input file name given as parameter) and triangulate points
Gudhi::Points_off_reader<std::vector <double>> off_reader(off_file_name);
@@ -69,7 +70,7 @@ int main(int argc, char * const argv[]) {
std::vector<std::vector< int > > knn;
Point_Vector landmarks;
Gudhi::subsampling::pick_n_random_points(point_vector, 100, std::back_inserter(landmarks));
- Gudhi::witness_complex::construct_closest_landmark_table(point_vector, landmarks, knn);
+ Gudhi::witness_complex::construct_closest_landmark_table<Simplex_tree::Filtration_value>(point_vector, landmarks, knn);
end = clock();
std::cout << "Landmark choice for " << nbL << " landmarks took "
<< static_cast<double>(end - start) / CLOCKS_PER_SEC << " s. \n";
diff --git a/src/Witness_complex/example/witness_complex_sphere.cpp b/src/Witness_complex/example/witness_complex_sphere.cpp
index e6f88274..7ab86cc0 100644
--- a/src/Witness_complex/example/witness_complex_sphere.cpp
+++ b/src/Witness_complex/example/witness_complex_sphere.cpp
@@ -40,6 +40,8 @@
#include "generators.h"
+typedef Gudhi::Simplex_tree<> Simplex_tree;
+
/** Write a gnuplot readable file.
* Data range is a random access range of pairs (arg, value)
*/
@@ -62,7 +64,7 @@ int main(int argc, char * const argv[]) {
clock_t start, end;
// Construct the Simplex Tree
- Gudhi::Simplex_tree<> simplex_tree;
+ Simplex_tree simplex_tree;
std::vector< std::pair<int, double> > l_time;
@@ -77,7 +79,7 @@ int main(int argc, char * const argv[]) {
start = clock();
std::vector<std::vector< int > > knn;
Gudhi::subsampling::pick_n_random_points(point_vector, 100, std::back_inserter(landmarks));
- Gudhi::witness_complex::construct_closest_landmark_table(point_vector, landmarks, knn);
+ Gudhi::witness_complex::construct_closest_landmark_table<Simplex_tree::Filtration_value>(point_vector, landmarks, knn);
// Compute witness complex
Gudhi::witness_complex::witness_complex(knn, number_of_landmarks, point_vector[0].size(), simplex_tree);
diff --git a/src/Witness_complex/include/gudhi/Construct_closest_landmark_table.h b/src/Witness_complex/include/gudhi/Construct_closest_landmark_table.h
index ef711c34..ec93ae71 100644
--- a/src/Witness_complex/include/gudhi/Construct_closest_landmark_table.h
+++ b/src/Witness_complex/include/gudhi/Construct_closest_landmark_table.h
@@ -51,7 +51,8 @@ namespace witness_complex {
* Closest_landmark_range needs to have push_back operation.
*/
- template <typename WitnessContainer,
+ template <typename FiltrationValue,
+ typename WitnessContainer,
typename LandmarkContainer,
typename KNearestNeighbours>
void construct_closest_landmark_table(WitnessContainer const &points,
@@ -72,7 +73,8 @@ namespace witness_complex {
int landmarks_i = 0;
for (landmarks_it = landmarks.begin(), landmarks_i = 0; landmarks_it != landmarks.end();
++landmarks_it, landmarks_i++) {
- dist_i dist = std::make_pair(euclidean_distance(points[points_i], *landmarks_it), landmarks_i);
+ dist_i dist = std::make_pair(euclidean_distance<FiltrationValue>(points[points_i], *landmarks_it),
+ landmarks_i);
l_heap.push(dist);
}
for (int i = 0; i < dim + 1; i++) {
diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h
new file mode 100644
index 00000000..bcb89e00
--- /dev/null
+++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h
@@ -0,0 +1,105 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Siargey Kachanovich
+ *
+ * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LANDMARK_CHOICE_BY_FURTHEST_POINT_H_
+#define LANDMARK_CHOICE_BY_FURTHEST_POINT_H_
+
+#include <boost/range/size.hpp>
+
+#include <limits> // for numeric_limits<>
+#include <iterator>
+#include <algorithm> // for sort
+#include <vector>
+
+namespace Gudhi {
+
+namespace witness_complex {
+
+ typedef std::vector<int> typeVectorVertex;
+
+ /**
+ * \ingroup witness_complex
+ * \brief Landmark choice strategy by iteratively adding the furthest witness from the
+ * current landmark set as the new landmark.
+ * \details It chooses nbL landmarks from a random access range `points` and
+ * writes {witness}*{closest landmarks} matrix in `knn`.
+ *
+ * The type KNearestNeighbors can be seen as
+ * Witness_range<Closest_landmark_range<Vertex_handle>>, where
+ * Witness_range and Closest_landmark_range are random access ranges
+ *
+ */
+
+ template <typename KNearestNeighbours,
+ typename Point_random_access_range>
+ void landmark_choice_by_furthest_point(Point_random_access_range const &points,
+ int nbL,
+ KNearestNeighbours &knn) {
+ int nb_points = boost::size(points);
+ assert(nb_points >= nbL);
+ // distance matrix witness x landmarks
+ std::vector<std::vector<double>> wit_land_dist(nb_points, std::vector<double>());
+ // landmark list
+ typeVectorVertex chosen_landmarks;
+
+ knn = KNearestNeighbours(nb_points, std::vector<int>());
+ int current_number_of_landmarks = 0; // counter for landmarks
+ double curr_max_dist = 0; // used for defining the furhest point from L
+ const double infty = std::numeric_limits<double>::infinity(); // infinity (see next entry)
+ std::vector< double > dist_to_L(nb_points, infty); // vector of current distances to L from points
+
+ // TODO(SK) Consider using rand_r(...) instead of rand(...) for improved thread safety
+ // or better yet std::uniform_int_distribution
+ int rand_int = rand() % nb_points;
+ int curr_max_w = rand_int; // For testing purposes a pseudo-random number is used here
+
+ for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) {
+ // curr_max_w at this point is the next landmark
+ chosen_landmarks.push_back(curr_max_w);
+ unsigned i = 0;
+ for (auto& p : points) {
+ double curr_dist = euclidean_distance<double>(p, *(std::begin(points) + chosen_landmarks[current_number_of_landmarks]));
+ wit_land_dist[i].push_back(curr_dist);
+ knn[i].push_back(current_number_of_landmarks);
+ if (curr_dist < dist_to_L[i])
+ dist_to_L[i] = curr_dist;
+ ++i;
+ }
+ curr_max_dist = 0;
+ for (i = 0; i < dist_to_L.size(); i++)
+ if (dist_to_L[i] > curr_max_dist) {
+ curr_max_dist = dist_to_L[i];
+ curr_max_w = i;
+ }
+ }
+ for (int i = 0; i < nb_points; ++i)
+ std::sort(std::begin(knn[i]),
+ std::end(knn[i]),
+ [&wit_land_dist, i](int a, int b) {
+ return wit_land_dist[i][a] < wit_land_dist[i][b]; });
+ }
+
+} // namespace witness_complex
+
+} // namespace Gudhi
+
+#endif // LANDMARK_CHOICE_BY_FURTHEST_POINT_H_
diff --git a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h
new file mode 100644
index 00000000..b5aab9d5
--- /dev/null
+++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h
@@ -0,0 +1,96 @@
+/* This file is part of the Gudhi Library. The Gudhi library
+ * (Geometric Understanding in Higher Dimensions) is a generic C++
+ * library for computational topology.
+ *
+ * Author(s): Siargey Kachanovich
+ *
+ * Copyright (C) 2015 INRIA Sophia Antipolis-Méditerranée (France)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LANDMARK_CHOICE_BY_RANDOM_POINT_H_
+#define LANDMARK_CHOICE_BY_RANDOM_POINT_H_
+
+#include <boost/range/size.hpp>
+
+#include <queue> // for priority_queue<>
+#include <utility> // for pair<>
+#include <iterator>
+#include <vector>
+#include <set>
+
+namespace Gudhi {
+
+namespace witness_complex {
+
+ /**
+ * \ingroup witness_complex
+ * \brief Landmark choice strategy by taking random vertices for landmarks.
+ * \details It chooses nbL distinct landmarks from a random access range `points`
+ * and outputs a matrix {witness}*{closest landmarks} in knn.
+ *
+ * The type KNearestNeighbors can be seen as
+ * Witness_range<Closest_landmark_range<Vertex_handle>>, where
+ * Witness_range and Closest_landmark_range are random access ranges and
+ * Vertex_handle is the label type of a vertex in a simplicial complex.
+ * Closest_landmark_range needs to have push_back operation.
+ */
+
+ template <typename KNearestNeighbours,
+ typename Point_random_access_range>
+ void landmark_choice_by_random_point(Point_random_access_range const &points,
+ int nbL,
+ KNearestNeighbours &knn) {
+ int nbP = boost::size(points);
+ assert(nbP >= nbL);
+ std::set<int> landmarks;
+ int current_number_of_landmarks = 0; // counter for landmarks
+
+ // TODO(SK) Consider using rand_r(...) instead of rand(...) for improved thread safety
+ int chosen_landmark = rand() % nbP;
+ for (current_number_of_landmarks = 0; current_number_of_landmarks != nbL; current_number_of_landmarks++) {
+ while (landmarks.find(chosen_landmark) != landmarks.end())
+ chosen_landmark = rand() % nbP;
+ landmarks.insert(chosen_landmark);
+ }
+
+ int dim = boost::size(*std::begin(points));
+ typedef std::pair<double, int> dist_i;
+ typedef bool (*comp)(dist_i, dist_i);
+ knn = KNearestNeighbours(nbP);
+ for (int points_i = 0; points_i < nbP; points_i++) {
+ std::priority_queue<dist_i, std::vector<dist_i>, comp> l_heap([](dist_i j1, dist_i j2) {
+ return j1.first > j2.first;
+ });
+ std::set<int>::iterator landmarks_it;
+ int landmarks_i = 0;
+ for (landmarks_it = landmarks.begin(), landmarks_i = 0; landmarks_it != landmarks.end();
+ ++landmarks_it, landmarks_i++) {
+ dist_i dist = std::make_pair(euclidean_distance<double>(points[points_i], points[*landmarks_it]), landmarks_i);
+ l_heap.push(dist);
+ }
+ for (int i = 0; i < dim + 1; i++) {
+ dist_i dist = l_heap.top();
+ knn[points_i].push_back(dist.second);
+ l_heap.pop();
+ }
+ }
+ }
+
+} // namespace witness_complex
+
+} // namespace Gudhi
+
+#endif // LANDMARK_CHOICE_BY_RANDOM_POINT_H_
diff --git a/src/Witness_complex/include/gudhi/Witness_complex.h b/src/Witness_complex/include/gudhi/Witness_complex.h
index 489cdf11..2cec921a 100644
--- a/src/Witness_complex/include/gudhi/Witness_complex.h
+++ b/src/Witness_complex/include/gudhi/Witness_complex.h
@@ -72,7 +72,7 @@ class Witness_complex {
typedef std::vector< Point_t > Point_Vector;
typedef std::vector< Vertex_handle > typeVectorVertex;
- typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex;
+ //typedef std::pair< typeVectorVertex, Filtration_value> typeSimplex;
typedef std::pair< Simplex_handle, bool > typePairSimplexBool;
typedef int Witness_id;
diff --git a/src/Witness_complex/test/simple_witness_complex.cpp b/src/Witness_complex/test/simple_witness_complex.cpp
index 03df78ee..adaadfb0 100644
--- a/src/Witness_complex/test/simple_witness_complex.cpp
+++ b/src/Witness_complex/test/simple_witness_complex.cpp
@@ -33,7 +33,7 @@
#include <vector>
typedef Gudhi::Simplex_tree<> Simplex_tree;
-typedef std::vector< Vertex_handle > typeVectorVertex;
+typedef std::vector< int > typeVectorVertex;
typedef Gudhi::witness_complex::Witness_complex<Simplex_tree> WitnessComplex;
BOOST_AUTO_TEST_CASE(simple_witness_complex) {
diff --git a/src/Witness_complex/test/witness_complex_points.cpp b/src/Witness_complex/test/witness_complex_points.cpp
index d40bbf14..b7067f87 100644
--- a/src/Witness_complex/test/witness_complex_points.cpp
+++ b/src/Witness_complex/test/witness_complex_points.cpp
@@ -34,7 +34,7 @@
#include <vector>
typedef std::vector<double> Point;
-typedef std::vector< Vertex_handle > typeVectorVertex;
+typedef std::vector< int > typeVectorVertex;
typedef Gudhi::Simplex_tree<> Simplex_tree;
typedef Gudhi::witness_complex::Witness_complex<Simplex_tree> WitnessComplex;
@@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(witness_complex_points) {
// First test: random choice
Simplex_tree complex1;
Gudhi::subsampling::pick_n_random_points(points, 100, std::back_inserter(landmarks));
- Gudhi::witness_complex::construct_closest_landmark_table(points, landmarks, knn);
+ Gudhi::witness_complex::construct_closest_landmark_table<Simplex_tree::Filtration_value>(points, landmarks, knn);
assert(!knn.empty());
WitnessComplex witnessComplex1(knn, 100, 3, complex1);
BOOST_CHECK(witnessComplex1.is_witness_complex(knn, b_print_output));