From 1c1c3073e0612ee401a941008a6b13438b3429e2 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 29 Sep 2016 12:34:19 +0000 Subject: Fix doxygen Add tests git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/rips_complex_module@1589 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3b03e969f43f4f41c7bca1b2de96a71688475742 --- src/Rips_complex/test/test_rips_complex.cpp | 231 ++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 src/Rips_complex/test/test_rips_complex.cpp (limited to 'src/Rips_complex/test/test_rips_complex.cpp') diff --git a/src/Rips_complex/test/test_rips_complex.cpp b/src/Rips_complex/test/test_rips_complex.cpp new file mode 100644 index 00000000..5f129160 --- /dev/null +++ b/src/Rips_complex/test/test_rips_complex.cpp @@ -0,0 +1,231 @@ +/* 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): Vincent Rouvreau + * + * Copyright (C) 2016 INRIA Saclay (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 . + */ + +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MODULE "rips_complex" +#include + +#include // float comparison +#include +#include +#include +#include // std::max + +#include +// to construct Rips_complex from a OFF file of points +#include +// to construct a simplex_tree from rips complex +#include +#include + +// Type definitions +using Point = std::vector; +using Simplex_tree = Gudhi::Simplex_tree<>; +using Rips_complex = Gudhi::rips_complex::Rips_complex; + +bool are_almost_the_same(float a, float b) { + return std::fabs(a - b) < std::numeric_limits::epsilon(); +} + +BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { + // ---------------------------------------------------------------------------- + // + // Init of a rips complex from a OFF file + // + // ---------------------------------------------------------------------------- + std::string off_file_name("alphacomplexdoc.off"); + double rips_threshold = 12.0; + std::cout << "========== OFF FILE NAME = " << off_file_name << " - rips threshold=" << + rips_threshold << "==========" << std::endl; + + Gudhi::Points_off_reader off_reader(off_file_name); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, euclidean_distance); + + const int DIMENSION_1 = 1; + Simplex_tree st; + BOOST_CHECK(rips_complex_from_file.create_complex(st, DIMENSION_1)); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == DIMENSION_1); + + const int NUMBER_OF_VERTICES = 7; + std::cout << "st.num_vertices()=" << st.num_vertices() << std::endl; + BOOST_CHECK(st.num_vertices() == NUMBER_OF_VERTICES); + + std::cout << "st.num_simplices()=" << st.num_simplices() << std::endl; + BOOST_CHECK(st.num_simplices() == 18); + + // Check filtration values of vertices is 0.0 + for (auto f_simplex : st.skeleton_simplex_range(0)) { + BOOST_CHECK(st.filtration(f_simplex) == 0.0); + } + + // Check filtration values of edges + for (auto f_simplex : st.skeleton_simplex_range(DIMENSION_1)) { + if (DIMENSION_1 == st.dimension(f_simplex)) { + std::vector vp; + std::cout << "vertex = ("; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << vertex << ","; + vp.push_back(off_reader.get_point_cloud().at(vertex)); + } + std::cout << ") - distance =" << euclidean_distance(vp.at(0), vp.at(1)) << + " - filtration =" << st.filtration(f_simplex) << std::endl; + BOOST_CHECK(vp.size() == 2); + BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), euclidean_distance(vp.at(0), vp.at(1)))); + } + } + + const int DIMENSION_2 = 2; + Simplex_tree st2; + BOOST_CHECK(rips_complex_from_file.create_complex(st2, DIMENSION_2)); + std::cout << "st2.dimension()=" << st2.dimension() << std::endl; + BOOST_CHECK(st2.dimension() == DIMENSION_2); + + std::cout << "st2.num_vertices()=" << st2.num_vertices() << std::endl; + BOOST_CHECK(st2.num_vertices() == NUMBER_OF_VERTICES); + + std::cout << "st2.num_simplices()=" << st2.num_simplices() << std::endl; + BOOST_CHECK(st2.num_simplices() == 23); + + Simplex_tree::Filtration_value f01 = st2.filtration(st2.find({0, 1})); + Simplex_tree::Filtration_value f02 = st2.filtration(st2.find({0, 2})); + Simplex_tree::Filtration_value f12 = st2.filtration(st2.find({1, 2})); + Simplex_tree::Filtration_value f012 = st2.filtration(st2.find({0, 1, 2})); + std::cout << "f012= " << f012 << " | f01= " << f01 << " - f02= " << f02 << " - f12= " << f12 << std::endl; + BOOST_CHECK(are_almost_the_same(f012, std::max(f01, std::max(f02,f12)))); + + Simplex_tree::Filtration_value f45 = st2.filtration(st2.find({4, 5})); + Simplex_tree::Filtration_value f56 = st2.filtration(st2.find({5, 6})); + Simplex_tree::Filtration_value f46 = st2.filtration(st2.find({4, 6})); + Simplex_tree::Filtration_value f456 = st2.filtration(st2.find({4, 5, 6})); + std::cout << "f456= " << f456 << " | f45= " << f45 << " - f56= " << f56 << " - f46= " << f46 << std::endl; + BOOST_CHECK(are_almost_the_same(f456, std::max(f45, std::max(f56,f46)))); + + const int DIMENSION_3 = 3; + Simplex_tree st3; + BOOST_CHECK(rips_complex_from_file.create_complex(st3, DIMENSION_3)); + std::cout << "st3.dimension()=" << st3.dimension() << std::endl; + BOOST_CHECK(st3.dimension() == DIMENSION_3); + + std::cout << "st3.num_vertices()=" << st3.num_vertices() << std::endl; + BOOST_CHECK(st3.num_vertices() == NUMBER_OF_VERTICES); + + std::cout << "st3.num_simplices()=" << st3.num_simplices() << std::endl; + BOOST_CHECK(st3.num_simplices() == 24); + + Simplex_tree::Filtration_value f123 = st3.filtration(st3.find({1, 2, 3})); + Simplex_tree::Filtration_value f013 = st3.filtration(st3.find({0, 1, 3})); + Simplex_tree::Filtration_value f023 = st3.filtration(st3.find({0, 2, 3})); + Simplex_tree::Filtration_value f0123 = st3.filtration(st3.find({0, 1, 2, 3})); + std::cout << "f0123= " << f0123 << " | f012= " << f012 << " - f123= " << f123 << " - f013= " << f013 << + " - f023= " << f023 << std::endl; + BOOST_CHECK(are_almost_the_same(f0123, std::max(f012, std::max(f123, std::max(f013, f023))))); + +} + +using Vector_of_points = std::vector; + +bool is_point_in_list(Vector_of_points points_list, Point point) { + for (auto& point_in_list : points_list) { + if (point_in_list == point) { + return true; // point found + } + } + return false; // point not found +} + +/* Compute the square value of Euclidean distance between two Points given by a range of coordinates. + * The points are assumed to have the same dimension. */ +template< typename Point > +double custom_square_euclidean_distance(const Point &p1,const Point &p2) { + double dist = 0.; + auto it1 = p1.begin(); + auto it2 = p2.begin(); + for (; it1 != p1.end(); ++it1, ++it2) { + double tmp = *it1 - *it2; + dist += tmp*tmp; + } + return dist; +} + +BOOST_AUTO_TEST_CASE(Rips_complex_from_points) { + // ---------------------------------------------------------------------------- + // Init of a list of points + // ---------------------------------------------------------------------------- + Vector_of_points points; + std::vector coords = { 0.0, 0.0, 0.0, 1.0 }; + points.push_back(Point(coords.begin(), coords.end())); + coords = { 0.0, 0.0, 1.0, 0.0 }; + points.push_back(Point(coords.begin(), coords.end())); + coords = { 0.0, 1.0, 0.0, 0.0 }; + points.push_back(Point(coords.begin(), coords.end())); + coords = { 1.0, 0.0, 0.0, 0.0 }; + points.push_back(Point(coords.begin(), coords.end())); + + // ---------------------------------------------------------------------------- + // Init of a rips complex from the list of points + // ---------------------------------------------------------------------------- + Rips_complex rips_complex_from_points(points, 2.0, custom_square_euclidean_distance); + + std::cout << "========== Rips_complex_from_points ==========" << std::endl; + Simplex_tree st; + const int DIMENSION = 3; + BOOST_CHECK(rips_complex_from_points.create_complex(st, DIMENSION)); + + // Another way to check num_simplices + std::cout << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << std::endl; + int num_simplices = 0; + for (auto f_simplex : st.filtration_simplex_range()) { + num_simplices++; + std::cout << " ( "; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << vertex << " "; + } + std::cout << ") -> " << "[" << st.filtration(f_simplex) << "] "; + std::cout << std::endl; + } + BOOST_CHECK(num_simplices == 15); + std::cout << "st.num_simplices()=" << st.num_simplices() << std::endl; + BOOST_CHECK(st.num_simplices() == 15); + + std::cout << "st.dimension()=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == DIMENSION); + std::cout << "st.num_vertices()=" << st.num_vertices() << std::endl; + BOOST_CHECK(st.num_vertices() == 4); + + for (auto f_simplex : st.filtration_simplex_range()) { + std::cout << "dimension(" << st.dimension(f_simplex) << ") - f = " << st.filtration(f_simplex) << std::endl; + switch (st.dimension(f_simplex)) { + case 0: + BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), 0.0)); + break; + case 1: + case 2: + case 3: + BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), 2.0)); + break; + default: + BOOST_CHECK(false); // Shall not happen + break; + } + } +} -- cgit v1.2.3 From 5ce7c7c8ec1378439cdc02dc94ac2a7e14e9ca04 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 3 Oct 2016 15:17:04 +0000 Subject: Fix euclidean distance for rips git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/rips_complex_module@1610 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: a07dfd4ffe3f17bf242ffb5b57058e99171a8016 --- src/GudhUI/utils/Persistence_compute.h | 2 +- .../benchmark/performance_rips_persistence.cpp | 4 ++-- .../example/rips_multifield_persistence.cpp | 4 ++-- src/Persistent_cohomology/example/rips_persistence.cpp | 4 ++-- .../example/rips_persistence_via_boundary_matrix.cpp | 2 +- .../example/example_one_skeleton_rips_from_points.cpp | 9 +++++---- src/Rips_complex/example/example_rips_complex_from_off_file.cpp | 5 +++-- src/Rips_complex/test/test_rips_complex.cpp | 8 +++++--- .../include/gudhi/Landmark_choice_by_furthest_point.h | 2 +- .../include/gudhi/Landmark_choice_by_random_point.h | 2 +- src/common/include/gudhi/distance_functions.h | 8 ++++---- 11 files changed, 27 insertions(+), 23 deletions(-) (limited to 'src/Rips_complex/test/test_rips_complex.cpp') diff --git a/src/GudhUI/utils/Persistence_compute.h b/src/GudhUI/utils/Persistence_compute.h index fa5bafc1..f7048c28 100644 --- a/src/GudhUI/utils/Persistence_compute.h +++ b/src/GudhUI/utils/Persistence_compute.h @@ -76,7 +76,7 @@ template class Persistence_compute { using Field_Zp = Gudhi::persistent_cohomology::Field_Zp; using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology; - Rips_complex rips_complex(points, params.threshold, euclidean_distance); + Rips_complex rips_complex(points, params.threshold, euclidean_distance); Simplex_tree st; if (rips_complex.create_complex(st, params.max_dim)) { diff --git a/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp b/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp index 99fcad41..a9eab5dd 100644 --- a/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp +++ b/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp @@ -33,7 +33,7 @@ #include // Types definition -using Simplex_tree = Gudhi::Simplex_tree; +using Simplex_tree = Gudhi::Simplex_tree; using Filtration_value = Simplex_tree::Filtration_value; using Rips_complex = Gudhi::rips_complex::Rips_complex; using Field_Zp = Gudhi::persistent_cohomology::Field_Zp; @@ -84,7 +84,7 @@ int main(int argc, char * argv[]) { // Compute the proximity graph of the points start = std::chrono::system_clock::now(); Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + euclidean_distance); end = std::chrono::system_clock::now(); elapsed_sec = std::chrono::duration_cast(end - start).count(); std::cout << "Compute Rips graph in " << elapsed_sec << " ms.\n"; diff --git a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp index f4adc7a9..8e5c83a1 100644 --- a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp +++ b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp @@ -33,7 +33,7 @@ #include // Types definition -using Simplex_tree = Gudhi::Simplex_tree; +using Simplex_tree = Gudhi::Simplex_tree; using Filtration_value = Simplex_tree::Filtration_value; using Rips_complex = Gudhi::rips_complex::Rips_complex; using Multi_field = Gudhi::persistent_cohomology::Multi_field; @@ -63,7 +63,7 @@ int main(int argc, char * argv[]) { Points_off_reader off_reader(off_file_points); Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + euclidean_distance); // Construct the Rips complex in a Simplex Tree Simplex_tree simplex_tree; diff --git a/src/Persistent_cohomology/example/rips_persistence.cpp b/src/Persistent_cohomology/example/rips_persistence.cpp index 97bab14c..b74d0094 100644 --- a/src/Persistent_cohomology/example/rips_persistence.cpp +++ b/src/Persistent_cohomology/example/rips_persistence.cpp @@ -34,7 +34,7 @@ #include // infinity // Types definition -using Simplex_tree = Gudhi::Simplex_tree; +using Simplex_tree = Gudhi::Simplex_tree; using Filtration_value = Simplex_tree::Filtration_value; using Rips_complex = Gudhi::rips_complex::Rips_complex; using Field_Zp = Gudhi::persistent_cohomology::Field_Zp; @@ -62,7 +62,7 @@ int main(int argc, char * argv[]) { Points_off_reader off_reader(off_file_points); Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + euclidean_distance); // Construct the Rips complex in a Simplex Tree Simplex_tree simplex_tree; diff --git a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp index 991ed4f0..ee6577f4 100644 --- a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp +++ b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp @@ -72,7 +72,7 @@ int main(int argc, char * argv[]) { Points_off_reader off_reader(off_file_points); Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + euclidean_distance); // Construct the Rips complex in a Simplex Tree Simplex_tree& st = *new Simplex_tree; diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp index db41b425..2e63d9a6 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp @@ -23,8 +23,9 @@ int main(int argc, char **argv) { // Type definitions using Point = std::vector; - using Simplex_tree = Gudhi::Simplex_tree<>; - using Rips_complex = Gudhi::rips_complex::Rips_complex; + using Simplex_tree = Gudhi::Simplex_tree; + using Filtration_value = Simplex_tree::Filtration_value; + using Rips_complex = Gudhi::rips_complex::Rips_complex; std::vector points; points.push_back({1.0, 1.0}); @@ -38,10 +39,10 @@ int main(int argc, char **argv) { // ---------------------------------------------------------------------------- // Init of a rips complex from points // ---------------------------------------------------------------------------- - Rips_complex rips_complex_from_file(points, threshold, euclidean_distance); + Rips_complex rips_complex_from_points(points, threshold, euclidean_distance); Simplex_tree simplex; - if (rips_complex_from_file.create_complex(simplex, 1)) { + if (rips_complex_from_points.create_complex(simplex, 1)) { // ---------------------------------------------------------------------------- // Display information about the one skeleton rips complex // ---------------------------------------------------------------------------- diff --git a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp index 82baa68e..60050cea 100644 --- a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp @@ -25,14 +25,15 @@ int main(int argc, char **argv) { // Type definitions using Point = std::vector; using Simplex_tree = Gudhi::Simplex_tree<>; - using Rips_complex = Gudhi::rips_complex::Rips_complex; + using Filtration_value = Simplex_tree::Filtration_value; + using Rips_complex = Gudhi::rips_complex::Rips_complex; // ---------------------------------------------------------------------------- // Init of a rips complex from an OFF file // ---------------------------------------------------------------------------- Gudhi::Points_off_reader off_reader(off_file_name); Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + euclidean_distance); std::streambuf* streambufffer; std::ofstream ouput_file_stream; diff --git a/src/Rips_complex/test/test_rips_complex.cpp b/src/Rips_complex/test/test_rips_complex.cpp index 5f129160..f8be9748 100644 --- a/src/Rips_complex/test/test_rips_complex.cpp +++ b/src/Rips_complex/test/test_rips_complex.cpp @@ -40,6 +40,7 @@ // Type definitions using Point = std::vector; using Simplex_tree = Gudhi::Simplex_tree<>; +using Filtration_value = Simplex_tree::Filtration_value; using Rips_complex = Gudhi::rips_complex::Rips_complex; bool are_almost_the_same(float a, float b) { @@ -58,7 +59,8 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { rips_threshold << "==========" << std::endl; Gudhi::Points_off_reader off_reader(off_file_name); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, euclidean_distance); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, + euclidean_distance); const int DIMENSION_1 = 1; Simplex_tree st; @@ -87,10 +89,10 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { std::cout << vertex << ","; vp.push_back(off_reader.get_point_cloud().at(vertex)); } - std::cout << ") - distance =" << euclidean_distance(vp.at(0), vp.at(1)) << + std::cout << ") - distance =" << euclidean_distance(vp.at(0), vp.at(1)) << " - filtration =" << st.filtration(f_simplex) << std::endl; BOOST_CHECK(vp.size() == 2); - BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), euclidean_distance(vp.at(0), vp.at(1)))); + BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), euclidean_distance(vp.at(0), vp.at(1)))); } } 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 index df93155b..bcb89e00 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_furthest_point.h @@ -77,7 +77,7 @@ namespace witness_complex { chosen_landmarks.push_back(curr_max_w); unsigned i = 0; for (auto& p : points) { - double curr_dist = euclidean_distance(p, *(std::begin(points) + chosen_landmarks[current_number_of_landmarks])); + double curr_dist = euclidean_distance(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]) 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 index ebf6aad1..b5aab9d5 100644 --- a/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h +++ b/src/Witness_complex/include/gudhi/Landmark_choice_by_random_point.h @@ -78,7 +78,7 @@ 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], points[*landmarks_it]), landmarks_i); + dist_i dist = std::make_pair(euclidean_distance(points[points_i], points[*landmarks_it]), landmarks_i); l_heap.push(dist); } for (int i = 0; i < dim + 1; i++) { diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h index b2726ba8..006df275 100644 --- a/src/common/include/gudhi/distance_functions.h +++ b/src/common/include/gudhi/distance_functions.h @@ -28,13 +28,13 @@ /* Compute the Euclidean distance between two Points given * by a range of coordinates. The points are assumed to have * the same dimension. */ -template< typename Point > -double euclidean_distance(const Point &p1,const Point &p2) { - double dist = 0.; +template< typename Filtration_value, typename Point > +Filtration_value euclidean_distance(const Point &p1,const Point &p2) { + Filtration_value dist = 0.; auto it1 = p1.begin(); auto it2 = p2.begin(); for (; it1 != p1.end(); ++it1, ++it2) { - double tmp = *it1 - *it2; + Filtration_value tmp = (double)(*it1) - (double)(*it2); dist += tmp*tmp; } return std::sqrt(dist); -- cgit v1.2.3 From 759b7d6fd92fa8666c41fb3acdb3158d744134c3 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Tue, 22 Nov 2016 14:22:16 +0000 Subject: Add distance matrix Unitary test git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/distance_matrix_in_rips_module@1768 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 566a69cf00976360c07084ce5df48fcc02f6653f --- src/Rips_complex/test/CMakeLists.txt | 1 + src/Rips_complex/test/test_rips_complex.cpp | 97 +++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) (limited to 'src/Rips_complex/test/test_rips_complex.cpp') diff --git a/src/Rips_complex/test/CMakeLists.txt b/src/Rips_complex/test/CMakeLists.txt index 3972e9fc..87bad2ed 100644 --- a/src/Rips_complex/test/CMakeLists.txt +++ b/src/Rips_complex/test/CMakeLists.txt @@ -18,6 +18,7 @@ endif() # Do not forget to copy test files in current binary dir file(COPY "${CMAKE_SOURCE_DIR}/data/points/alphacomplexdoc.off" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) +file(COPY "${CMAKE_SOURCE_DIR}/data/distance_matrix/full_square_distance_matrix.csv" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) add_test(rips_complex_UT ${CMAKE_CURRENT_BINARY_DIR}/rips_complex_UT # XML format for Jenkins xUnit plugin diff --git a/src/Rips_complex/test/test_rips_complex.cpp b/src/Rips_complex/test/test_rips_complex.cpp index f8be9748..faedbf4a 100644 --- a/src/Rips_complex/test/test_rips_complex.cpp +++ b/src/Rips_complex/test/test_rips_complex.cpp @@ -36,12 +36,14 @@ // to construct a simplex_tree from rips complex #include #include +#include // Type definitions using Point = std::vector; using Simplex_tree = Gudhi::Simplex_tree<>; using Filtration_value = Simplex_tree::Filtration_value; using Rips_complex = Gudhi::rips_complex::Rips_complex; +using Distance_matrix = std::vector>; bool are_almost_the_same(float a, float b) { return std::fabs(a - b) < std::numeric_limits::epsilon(); @@ -231,3 +233,98 @@ BOOST_AUTO_TEST_CASE(Rips_complex_from_points) { } } } + +BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) { + // ---------------------------------------------------------------------------- + // + // Init of a rips complex from a OFF file + // + // ---------------------------------------------------------------------------- + std::string csv_file_name("full_square_distance_matrix.csv"); + double rips_threshold = 12.0; + std::cout << "========== CSV FILE NAME = " << csv_file_name << " - rips threshold=" << + rips_threshold << "==========" << std::endl; + + Distance_matrix distances = read_lower_triangular_matrix_from_csv_file(csv_file_name); + Rips_complex rips_complex_from_file(distances, rips_threshold); + + const int DIMENSION_1 = 1; + Simplex_tree st; + BOOST_CHECK(rips_complex_from_file.create_complex(st, DIMENSION_1)); + std::cout << "st.dimension()=" << st.dimension() << std::endl; + BOOST_CHECK(st.dimension() == DIMENSION_1); + + const int NUMBER_OF_VERTICES = 7; + std::cout << "st.num_vertices()=" << st.num_vertices() << std::endl; + BOOST_CHECK(st.num_vertices() == NUMBER_OF_VERTICES); + + std::cout << "st.num_simplices()=" << st.num_simplices() << std::endl; + BOOST_CHECK(st.num_simplices() == 18); + + // Check filtration values of vertices is 0.0 + for (auto f_simplex : st.skeleton_simplex_range(0)) { + BOOST_CHECK(st.filtration(f_simplex) == 0.0); + } + + // Check filtration values of edges + for (auto f_simplex : st.skeleton_simplex_range(DIMENSION_1)) { + if (DIMENSION_1 == st.dimension(f_simplex)) { + std::vector vvh; + std::cout << "vertex = ("; + for (auto vertex : st.simplex_vertex_range(f_simplex)) { + std::cout << vertex << ","; + vvh.push_back(vertex); + } + std::cout << ") - filtration =" << st.filtration(f_simplex) << std::endl; + BOOST_CHECK(vvh.size() == 2); + BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), distances[vvh.at(0)][vvh.at(1)])); + } + } + + const int DIMENSION_2 = 2; + Simplex_tree st2; + BOOST_CHECK(rips_complex_from_file.create_complex(st2, DIMENSION_2)); + std::cout << "st2.dimension()=" << st2.dimension() << std::endl; + BOOST_CHECK(st2.dimension() == DIMENSION_2); + + std::cout << "st2.num_vertices()=" << st2.num_vertices() << std::endl; + BOOST_CHECK(st2.num_vertices() == NUMBER_OF_VERTICES); + + std::cout << "st2.num_simplices()=" << st2.num_simplices() << std::endl; + BOOST_CHECK(st2.num_simplices() == 23); + + Simplex_tree::Filtration_value f01 = st2.filtration(st2.find({0, 1})); + Simplex_tree::Filtration_value f02 = st2.filtration(st2.find({0, 2})); + Simplex_tree::Filtration_value f12 = st2.filtration(st2.find({1, 2})); + Simplex_tree::Filtration_value f012 = st2.filtration(st2.find({0, 1, 2})); + std::cout << "f012= " << f012 << " | f01= " << f01 << " - f02= " << f02 << " - f12= " << f12 << std::endl; + BOOST_CHECK(are_almost_the_same(f012, std::max(f01, std::max(f02,f12)))); + + Simplex_tree::Filtration_value f45 = st2.filtration(st2.find({4, 5})); + Simplex_tree::Filtration_value f56 = st2.filtration(st2.find({5, 6})); + Simplex_tree::Filtration_value f46 = st2.filtration(st2.find({4, 6})); + Simplex_tree::Filtration_value f456 = st2.filtration(st2.find({4, 5, 6})); + std::cout << "f456= " << f456 << " | f45= " << f45 << " - f56= " << f56 << " - f46= " << f46 << std::endl; + BOOST_CHECK(are_almost_the_same(f456, std::max(f45, std::max(f56,f46)))); + + const int DIMENSION_3 = 3; + Simplex_tree st3; + BOOST_CHECK(rips_complex_from_file.create_complex(st3, DIMENSION_3)); + std::cout << "st3.dimension()=" << st3.dimension() << std::endl; + BOOST_CHECK(st3.dimension() == DIMENSION_3); + + std::cout << "st3.num_vertices()=" << st3.num_vertices() << std::endl; + BOOST_CHECK(st3.num_vertices() == NUMBER_OF_VERTICES); + + std::cout << "st3.num_simplices()=" << st3.num_simplices() << std::endl; + BOOST_CHECK(st3.num_simplices() == 24); + + Simplex_tree::Filtration_value f123 = st3.filtration(st3.find({1, 2, 3})); + Simplex_tree::Filtration_value f013 = st3.filtration(st3.find({0, 1, 3})); + Simplex_tree::Filtration_value f023 = st3.filtration(st3.find({0, 2, 3})); + Simplex_tree::Filtration_value f0123 = st3.filtration(st3.find({0, 1, 2, 3})); + std::cout << "f0123= " << f0123 << " | f012= " << f012 << " - f123= " << f123 << " - f013= " << f013 << + " - f023= " << f023 << std::endl; + BOOST_CHECK(are_almost_the_same(f0123, std::max(f012, std::max(f123, std::max(f013, f023))))); + +} \ No newline at end of file -- cgit v1.2.3 From b41fb07d4dbaf4e12c31b952cc2bc24e30c55384 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Thu, 8 Dec 2016 22:17:04 +0000 Subject: replace euclidean_distance with a class Euclidean_distance containing an operator() git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/distance_matrix_in_rips_module@1840 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: b1619401ac0ef978257709c5deeb7e19fbcff32c --- src/GudhUI/utils/Persistence_compute.h | 2 +- .../benchmark/performance_rips_persistence.cpp | 3 +- .../example/rips_multifield_persistence.cpp | 3 +- .../example/rips_persistence.cpp | 3 +- .../rips_persistence_via_boundary_matrix.cpp | 3 +- .../example_one_skeleton_rips_from_points.cpp | 2 +- .../example/example_rips_complex_from_off_file.cpp | 3 +- src/Rips_complex/test/test_rips_complex.cpp | 36 +++++++++++----------- .../gudhi/Construct_closest_landmark_table.h | 2 +- src/common/include/gudhi/distance_functions.h | 23 ++++++++------ 10 files changed, 39 insertions(+), 41 deletions(-) (limited to 'src/Rips_complex/test/test_rips_complex.cpp') diff --git a/src/GudhUI/utils/Persistence_compute.h b/src/GudhUI/utils/Persistence_compute.h index d2973d84..12283cbe 100644 --- a/src/GudhUI/utils/Persistence_compute.h +++ b/src/GudhUI/utils/Persistence_compute.h @@ -76,7 +76,7 @@ template class Persistence_compute { using Field_Zp = Gudhi::persistent_cohomology::Field_Zp; using Persistent_cohomology = Gudhi::persistent_cohomology::Persistent_cohomology; - Rips_complex rips_complex(points, params.threshold, euclidean_distance); + Rips_complex rips_complex(points, params.threshold, Euclidean_distance()); Simplex_tree st; if (rips_complex.create_complex(st, params.max_dim)) { diff --git a/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp b/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp index a9eab5dd..ba752999 100644 --- a/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp +++ b/src/Persistent_cohomology/benchmark/performance_rips_persistence.cpp @@ -83,8 +83,7 @@ int main(int argc, char * argv[]) { // Compute the proximity graph of the points start = std::chrono::system_clock::now(); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); end = std::chrono::system_clock::now(); elapsed_sec = std::chrono::duration_cast(end - start).count(); std::cout << "Compute Rips graph in " << elapsed_sec << " ms.\n"; diff --git a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp index aaa71db9..3389d8e1 100644 --- a/src/Persistent_cohomology/example/rips_multifield_persistence.cpp +++ b/src/Persistent_cohomology/example/rips_multifield_persistence.cpp @@ -62,8 +62,7 @@ int main(int argc, char * argv[]) { program_options(argc, argv, off_file_points, filediag, threshold, dim_max, min_p, max_p, min_persistence); Points_off_reader off_reader(off_file_points); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); // Construct the Rips complex in a Simplex Tree Simplex_tree simplex_tree; diff --git a/src/Persistent_cohomology/example/rips_persistence.cpp b/src/Persistent_cohomology/example/rips_persistence.cpp index 0b1873d4..bc62b736 100644 --- a/src/Persistent_cohomology/example/rips_persistence.cpp +++ b/src/Persistent_cohomology/example/rips_persistence.cpp @@ -61,8 +61,7 @@ int main(int argc, char * argv[]) { program_options(argc, argv, off_file_points, filediag, threshold, dim_max, p, min_persistence); Points_off_reader off_reader(off_file_points); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); // Construct the Rips complex in a Simplex Tree Simplex_tree simplex_tree; diff --git a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp index b7daf6ae..63da9847 100644 --- a/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp +++ b/src/Persistent_cohomology/example/rips_persistence_via_boundary_matrix.cpp @@ -70,8 +70,7 @@ int main(int argc, char * argv[]) { program_options(argc, argv, off_file_points, filediag, threshold, dim_max, p, min_persistence); Points_off_reader off_reader(off_file_points); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); // Construct the Rips complex in a Simplex Tree Simplex_tree& st = *new Simplex_tree; diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp index 68fc3629..e9e7ecd4 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp @@ -38,7 +38,7 @@ int main(int argc, char **argv) { // ---------------------------------------------------------------------------- // Init of a rips complex from points // ---------------------------------------------------------------------------- - Rips_complex rips_complex_from_points(points, threshold, euclidean_distance); + Rips_complex rips_complex_from_points(points, threshold, Euclidean_distance()); Simplex_tree simplex; if (rips_complex_from_points.create_complex(simplex, 1)) { diff --git a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp index 469de403..af2c7029 100644 --- a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp @@ -33,8 +33,7 @@ int main(int argc, char **argv) { // Init of a rips complex from an OFF file // ---------------------------------------------------------------------------- Gudhi::Points_off_reader off_reader(off_file_name); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, - euclidean_distance); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), threshold, Euclidean_distance()); std::streambuf* streambufffer; std::ofstream ouput_file_stream; diff --git a/src/Rips_complex/test/test_rips_complex.cpp b/src/Rips_complex/test/test_rips_complex.cpp index faedbf4a..2db1554d 100644 --- a/src/Rips_complex/test/test_rips_complex.cpp +++ b/src/Rips_complex/test/test_rips_complex.cpp @@ -61,8 +61,7 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { rips_threshold << "==========" << std::endl; Gudhi::Points_off_reader off_reader(off_file_name); - Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, - euclidean_distance); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, Euclidean_distance()); const int DIMENSION_1 = 1; Simplex_tree st; @@ -91,10 +90,10 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { std::cout << vertex << ","; vp.push_back(off_reader.get_point_cloud().at(vertex)); } - std::cout << ") - distance =" << euclidean_distance(vp.at(0), vp.at(1)) << + std::cout << ") - distance =" << Euclidean_distance()(vp.at(0), vp.at(1)) << " - filtration =" << st.filtration(f_simplex) << std::endl; BOOST_CHECK(vp.size() == 2); - BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), euclidean_distance(vp.at(0), vp.at(1)))); + BOOST_CHECK(are_almost_the_same(st.filtration(f_simplex), Euclidean_distance()(vp.at(0), vp.at(1)))); } } @@ -157,19 +156,20 @@ bool is_point_in_list(Vector_of_points points_list, Point point) { return false; // point not found } -/* Compute the square value of Euclidean distance between two Points given by a range of coordinates. - * The points are assumed to have the same dimension. */ -template< typename Point > -double custom_square_euclidean_distance(const Point &p1,const Point &p2) { - double dist = 0.; - auto it1 = p1.begin(); - auto it2 = p2.begin(); - for (; it1 != p1.end(); ++it1, ++it2) { - double tmp = *it1 - *it2; - dist += tmp*tmp; +class Custom_square_euclidean_distance { + public: + template< typename Point > + auto operator()(const Point& p1, const Point& p2) -> typename Point::value_type { + auto it1 = p1.begin(); + auto it2 = p2.begin(); + typename Point::value_type dist = 0.; + for (; it1 != p1.end(); ++it1, ++it2) { + typename Point::value_type tmp = (*it1) - (*it2); + dist += tmp*tmp; + } + return dist; } - return dist; -} +}; BOOST_AUTO_TEST_CASE(Rips_complex_from_points) { // ---------------------------------------------------------------------------- @@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(Rips_complex_from_points) { // ---------------------------------------------------------------------------- // Init of a rips complex from the list of points // ---------------------------------------------------------------------------- - Rips_complex rips_complex_from_points(points, 2.0, custom_square_euclidean_distance); + Rips_complex rips_complex_from_points(points, 2.0, Custom_square_euclidean_distance()); std::cout << "========== Rips_complex_from_points ==========" << std::endl; Simplex_tree st; @@ -327,4 +327,4 @@ BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) { " - f023= " << f023 << std::endl; BOOST_CHECK(are_almost_the_same(f0123, std::max(f012, std::max(f123, std::max(f013, f023))))); -} \ No newline at end of file +} 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 1ae2e393..a8cdd096 100644 --- a/src/Witness_complex/include/gudhi/Construct_closest_landmark_table.h +++ b/src/Witness_complex/include/gudhi/Construct_closest_landmark_table.h @@ -73,7 +73,7 @@ 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), + dist_i dist = std::make_pair(Euclidean_distance()(points[points_i], *landmarks_it), landmarks_i); l_heap.push(dist); } diff --git a/src/common/include/gudhi/distance_functions.h b/src/common/include/gudhi/distance_functions.h index 58a513e7..5c7f3d55 100644 --- a/src/common/include/gudhi/distance_functions.h +++ b/src/common/include/gudhi/distance_functions.h @@ -31,16 +31,19 @@ /** @brief Compute the Euclidean distance between two Points given by a range of coordinates. The points are assumed to * have the same dimension. */ -template< typename Filtration_value, typename Point > -Filtration_value euclidean_distance(const Point &p1, const Point &p2) { - Filtration_value dist = 0.; - auto it1 = p1.begin(); - auto it2 = p2.begin(); - for (; it1 != p1.end(); ++it1, ++it2) { - Filtration_value tmp = static_cast(*it1) - static_cast(*it2); - dist += tmp*tmp; +class Euclidean_distance { + public: + template< typename Point > + auto operator()(const Point& p1, const Point& p2) -> typename Point::value_type { + auto it1 = p1.begin(); + auto it2 = p2.begin(); + typename Point::value_type dist = 0.; + for (; it1 != p1.end(); ++it1, ++it2) { + typename Point::value_type tmp = (*it1) - (*it2); + dist += tmp*tmp; + } + return std::sqrt(dist); } - return std::sqrt(dist); -} +}; #endif // DISTANCE_FUNCTIONS_H_ -- cgit v1.2.3 From fc454f6135bc6f63a6eb859f58835fe653eb073d Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Mon, 12 Dec 2016 13:33:29 +0000 Subject: Remove comment // to construct a simplex_tree from rips complex git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/distance_matrix_in_rips_module@1855 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 2be10c7952457b0f6210c4bbbce82eaa250498a7 --- .../example/example_one_skeleton_rips_from_distance_matrix.cpp | 1 - src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp | 1 - .../example/example_rips_complex_from_csv_distance_matrix_file.cpp | 1 - src/Rips_complex/example/example_rips_complex_from_off_file.cpp | 1 - src/Rips_complex/test/test_rips_complex.cpp | 1 - 5 files changed, 5 deletions(-) (limited to 'src/Rips_complex/test/test_rips_complex.cpp') diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_distance_matrix.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_distance_matrix.cpp index b1ba494e..4d577822 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_distance_matrix.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_distance_matrix.cpp @@ -1,5 +1,4 @@ #include -// to construct a simplex_tree from rips complex #include #include diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp index e9e7ecd4..9e90c72e 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp @@ -1,5 +1,4 @@ #include -// to construct a simplex_tree from rips complex #include #include diff --git a/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp b/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp index 730bfc7c..93160b1b 100644 --- a/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp @@ -1,7 +1,6 @@ #include // to construct Rips_complex from a OFF file of points #include -// to construct a simplex_tree from rips complex #include #include diff --git a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp index af2c7029..23e49add 100644 --- a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp @@ -1,7 +1,6 @@ #include // to construct Rips_complex from a OFF file of points #include -// to construct a simplex_tree from rips complex #include #include diff --git a/src/Rips_complex/test/test_rips_complex.cpp b/src/Rips_complex/test/test_rips_complex.cpp index 2db1554d..7e0473d9 100644 --- a/src/Rips_complex/test/test_rips_complex.cpp +++ b/src/Rips_complex/test/test_rips_complex.cpp @@ -33,7 +33,6 @@ #include // to construct Rips_complex from a OFF file of points #include -// to construct a simplex_tree from rips complex #include #include #include -- cgit v1.2.3 From de2573cf2b2eb92cff628d9690a067b50b4ca145 Mon Sep 17 00:00:00 2001 From: vrouvrea Date: Wed, 14 Dec 2016 13:27:02 +0000 Subject: Rollback pointer modification, and use of of a hack for no deep copy of boost graph "voidification" of create_complex method git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/branches/distance_matrix_in_rips_module@1868 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 3667c8f57388dec0300d1fed8bf1b063843727dd --- ...mple_one_skeleton_rips_from_distance_matrix.cpp | 32 +++++++++--------- .../example_one_skeleton_rips_from_points.cpp | 33 +++++++++--------- ..._rips_complex_from_csv_distance_matrix_file.cpp | 34 +++++++++---------- .../example/example_rips_complex_from_off_file.cpp | 34 +++++++++---------- src/Rips_complex/include/gudhi/Rips_complex.h | 39 +++++++++------------- src/Rips_complex/test/test_rips_complex.cpp | 38 +++++++++++++++++---- 6 files changed, 112 insertions(+), 98 deletions(-) (limited to 'src/Rips_complex/test/test_rips_complex.cpp') diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_distance_matrix.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_distance_matrix.cpp index 02bffe0d..326ad52f 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_distance_matrix.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_distance_matrix.cpp @@ -45,24 +45,24 @@ int main(int argc, char **argv) { Rips_complex rips_complex_from_points(distances, threshold); Simplex_tree stree; - if (rips_complex_from_points.create_complex(stree, 1)) { - // ---------------------------------------------------------------------------- - // Display information about the one skeleton rips complex - // ---------------------------------------------------------------------------- - std::cout << "Rips complex is of dimension " << stree.dimension() << - " - " << stree.num_simplices() << " simplices - " << - stree.num_vertices() << " vertices." << std::endl; + rips_complex_from_points.create_complex(stree, 1); + // ---------------------------------------------------------------------------- + // Display information about the one skeleton rips complex + // ---------------------------------------------------------------------------- + std::cout << "Rips complex is of dimension " << stree.dimension() << + " - " << stree.num_simplices() << " simplices - " << + stree.num_vertices() << " vertices." << std::endl; - std::cout << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << - std::endl; - for (auto f_simplex : stree.filtration_simplex_range()) { - std::cout << " ( "; - for (auto vertex : stree.simplex_vertex_range(f_simplex)) { - std::cout << vertex << " "; - } - std::cout << ") -> " << "[" << stree.filtration(f_simplex) << "] "; - std::cout << std::endl; + std::cout << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << + std::endl; + for (auto f_simplex : stree.filtration_simplex_range()) { + std::cout << " ( "; + for (auto vertex : stree.simplex_vertex_range(f_simplex)) { + std::cout << vertex << " "; } + std::cout << ") -> " << "[" << stree.filtration(f_simplex) << "] "; + std::cout << std::endl; } + return 0; } diff --git a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp index efbcd88e..6e8dee27 100644 --- a/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp +++ b/src/Rips_complex/example/example_one_skeleton_rips_from_points.cpp @@ -40,24 +40,23 @@ int main(int argc, char **argv) { Rips_complex rips_complex_from_points(points, threshold, Euclidean_distance()); Simplex_tree stree; - if (rips_complex_from_points.create_complex(stree, 1)) { - // ---------------------------------------------------------------------------- - // Display information about the one skeleton rips complex - // ---------------------------------------------------------------------------- - std::cout << "Rips complex is of dimension " << stree.dimension() << - " - " << stree.num_simplices() << " simplices - " << - stree.num_vertices() << " vertices." << std::endl; - - std::cout << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << - std::endl; - for (auto f_simplex : stree.filtration_simplex_range()) { - std::cout << " ( "; - for (auto vertex : stree.simplex_vertex_range(f_simplex)) { - std::cout << vertex << " "; - } - std::cout << ") -> " << "[" << stree.filtration(f_simplex) << "] "; - std::cout << std::endl; + rips_complex_from_points.create_complex(stree, 1); + // ---------------------------------------------------------------------------- + // Display information about the one skeleton rips complex + // ---------------------------------------------------------------------------- + std::cout << "Rips complex is of dimension " << stree.dimension() << + " - " << stree.num_simplices() << " simplices - " << + stree.num_vertices() << " vertices." << std::endl; + + std::cout << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << + std::endl; + for (auto f_simplex : stree.filtration_simplex_range()) { + std::cout << " ( "; + for (auto vertex : stree.simplex_vertex_range(f_simplex)) { + std::cout << vertex << " "; } + std::cout << ") -> " << "[" << stree.filtration(f_simplex) << "] "; + std::cout << std::endl; } return 0; } diff --git a/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp b/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp index 7cdaffdf..cc6c3a33 100644 --- a/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_csv_distance_matrix_file.cpp @@ -46,27 +46,27 @@ int main(int argc, char **argv) { } Simplex_tree stree; - if (rips_complex_from_file.create_complex(stree, dim_max)) { - std::ostream output_stream(streambufffer); + rips_complex_from_file.create_complex(stree, dim_max); + std::ostream output_stream(streambufffer); - // ---------------------------------------------------------------------------- - // Display information about the rips complex - // ---------------------------------------------------------------------------- - output_stream << "Rips complex is of dimension " << stree.dimension() << - " - " << stree.num_simplices() << " simplices - " << - stree.num_vertices() << " vertices." << std::endl; + // ---------------------------------------------------------------------------- + // Display information about the rips complex + // ---------------------------------------------------------------------------- + output_stream << "Rips complex is of dimension " << stree.dimension() << + " - " << stree.num_simplices() << " simplices - " << + stree.num_vertices() << " vertices." << std::endl; - output_stream << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << - std::endl; - for (auto f_simplex : stree.filtration_simplex_range()) { - output_stream << " ( "; - for (auto vertex : stree.simplex_vertex_range(f_simplex)) { - output_stream << vertex << " "; - } - output_stream << ") -> " << "[" << stree.filtration(f_simplex) << "] "; - output_stream << std::endl; + output_stream << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << + std::endl; + for (auto f_simplex : stree.filtration_simplex_range()) { + output_stream << " ( "; + for (auto vertex : stree.simplex_vertex_range(f_simplex)) { + output_stream << vertex << " "; } + output_stream << ") -> " << "[" << stree.filtration(f_simplex) << "] "; + output_stream << std::endl; } + ouput_file_stream.close(); return 0; } diff --git a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp index 8849d784..b6c961d0 100644 --- a/src/Rips_complex/example/example_rips_complex_from_off_file.cpp +++ b/src/Rips_complex/example/example_rips_complex_from_off_file.cpp @@ -45,27 +45,27 @@ int main(int argc, char **argv) { } Simplex_tree stree; - if (rips_complex_from_file.create_complex(stree, dim_max)) { - std::ostream output_stream(streambufffer); + rips_complex_from_file.create_complex(stree, dim_max); + std::ostream output_stream(streambufffer); - // ---------------------------------------------------------------------------- - // Display information about the rips complex - // ---------------------------------------------------------------------------- - output_stream << "Rips complex is of dimension " << stree.dimension() << - " - " << stree.num_simplices() << " simplices - " << - stree.num_vertices() << " vertices." << std::endl; + // ---------------------------------------------------------------------------- + // Display information about the rips complex + // ---------------------------------------------------------------------------- + output_stream << "Rips complex is of dimension " << stree.dimension() << + " - " << stree.num_simplices() << " simplices - " << + stree.num_vertices() << " vertices." << std::endl; - output_stream << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << - std::endl; - for (auto f_simplex : stree.filtration_simplex_range()) { - output_stream << " ( "; - for (auto vertex : stree.simplex_vertex_range(f_simplex)) { - output_stream << vertex << " "; - } - output_stream << ") -> " << "[" << stree.filtration(f_simplex) << "] "; - output_stream << std::endl; + output_stream << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << + std::endl; + for (auto f_simplex : stree.filtration_simplex_range()) { + output_stream << " ( "; + for (auto vertex : stree.simplex_vertex_range(f_simplex)) { + output_stream << vertex << " "; } + output_stream << ") -> " << "[" << stree.filtration(f_simplex) << "] "; + output_stream << std::endl; } + ouput_file_stream.close(); return 0; } diff --git a/src/Rips_complex/include/gudhi/Rips_complex.h b/src/Rips_complex/include/gudhi/Rips_complex.h index 5ac46071..1061de73 100644 --- a/src/Rips_complex/include/gudhi/Rips_complex.h +++ b/src/Rips_complex/include/gudhi/Rips_complex.h @@ -73,8 +73,7 @@ class Rips_complex { * The type InputPointRange must be a range for which std::begin and std::end return input iterators on a point. */ template - Rips_complex(const InputPointRange& points, Filtration_value threshold, Distance distance) - : rips_skeleton_graph_(nullptr) { + Rips_complex(const InputPointRange& points, Filtration_value threshold, Distance distance) { compute_proximity_graph(points, threshold, distance); } @@ -88,8 +87,7 @@ class Rips_complex { * distance_matrix.size().\f$ */ template - Rips_complex(const InputDistanceRange& distance_matrix, Filtration_value threshold) - : rips_skeleton_graph_(nullptr) { + Rips_complex(const InputDistanceRange& distance_matrix, Filtration_value threshold) { compute_proximity_graph(boost::irange((size_t)0, distance_matrix.size()), threshold, [&](size_t i, size_t j){return distance_matrix[j][i];}); } @@ -101,28 +99,18 @@ class Rips_complex { * * @param[in] complex SimplicialComplexForRips to be created. * @param[in] dim_max graph expansion for rips until this given maximal dimension. - * - * @return true if creation succeeds, false otherwise. - * + * @exception std::invalid_argument In debug mode, if \code complex.num_vertices() \endcode does not return 0. + * */ template - bool create_complex(SimplicialComplexForRips& complex, int dim_max) { - if (complex.num_vertices() > 0) { - std::cerr << "Rips_complex create_complex - complex is not empty\n"; - return false; // ----- >> - } - if (rips_skeleton_graph_ == nullptr) { - std::cerr << "Rips Skeleton Graph is not defined\n"; - return false; // ----- >> - } + void create_complex(SimplicialComplexForRips& complex, int dim_max) { + GUDHI_CHECK(complex.num_vertices() == 0, + std::invalid_argument("Rips_complex::create_complex - simplicial complex is not empty")); // insert the proximity graph in the simplicial complex - complex.insert_graph(*rips_skeleton_graph_); + complex.insert_graph(rips_skeleton_graph_); // expand the graph until dimension dim_max complex.expansion(dim_max); - - // -------------------------------------------------------------------------------------------- - return true; } private: @@ -161,20 +149,23 @@ class Rips_complex { // -------------------------------------------------------------------------------------------- // Creates the proximity graph from edges and sets the property with the filtration value. // Number of points is labeled from 0 to idx_u-1 - rips_skeleton_graph_ = new Graph_t(edges.begin(), edges.end(), edges_fil.begin(), idx_u); + // -------------------------------------------------------------------------------------------- + // Do not use : rips_skeleton_graph_ = Graph_t(...) -> deep copy of the graph (boost graph is not move-enabled) + rips_skeleton_graph_.~Graph_t(); + new(&rips_skeleton_graph_)Graph_t(edges.begin(), edges.end(), edges_fil.begin(), idx_u); - auto vertex_prop = boost::get(vertex_filtration_t(), *rips_skeleton_graph_); + auto vertex_prop = boost::get(vertex_filtration_t(), rips_skeleton_graph_); using vertex_iterator = typename boost::graph_traits::vertex_iterator; vertex_iterator vi, vi_end; - for (std::tie(vi, vi_end) = boost::vertices(*rips_skeleton_graph_); + for (std::tie(vi, vi_end) = boost::vertices(rips_skeleton_graph_); vi != vi_end; ++vi) { boost::put(vertex_prop, *vi, 0.); } } private: - Graph_t* rips_skeleton_graph_; + Graph_t rips_skeleton_graph_; }; } // namespace rips_complex diff --git a/src/Rips_complex/test/test_rips_complex.cpp b/src/Rips_complex/test/test_rips_complex.cpp index 7e0473d9..1bdd0512 100644 --- a/src/Rips_complex/test/test_rips_complex.cpp +++ b/src/Rips_complex/test/test_rips_complex.cpp @@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { const int DIMENSION_1 = 1; Simplex_tree st; - BOOST_CHECK(rips_complex_from_file.create_complex(st, DIMENSION_1)); + rips_complex_from_file.create_complex(st, DIMENSION_1); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == DIMENSION_1); @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { const int DIMENSION_2 = 2; Simplex_tree st2; - BOOST_CHECK(rips_complex_from_file.create_complex(st2, DIMENSION_2)); + rips_complex_from_file.create_complex(st2, DIMENSION_2); std::cout << "st2.dimension()=" << st2.dimension() << std::endl; BOOST_CHECK(st2.dimension() == DIMENSION_2); @@ -124,7 +124,7 @@ BOOST_AUTO_TEST_CASE(RIPS_DOC_OFF_file) { const int DIMENSION_3 = 3; Simplex_tree st3; - BOOST_CHECK(rips_complex_from_file.create_complex(st3, DIMENSION_3)); + rips_complex_from_file.create_complex(st3, DIMENSION_3); std::cout << "st3.dimension()=" << st3.dimension() << std::endl; BOOST_CHECK(st3.dimension() == DIMENSION_3); @@ -192,7 +192,7 @@ BOOST_AUTO_TEST_CASE(Rips_complex_from_points) { std::cout << "========== Rips_complex_from_points ==========" << std::endl; Simplex_tree st; const int DIMENSION = 3; - BOOST_CHECK(rips_complex_from_points.create_complex(st, DIMENSION)); + rips_complex_from_points.create_complex(st, DIMENSION); // Another way to check num_simplices std::cout << "Iterator on rips complex simplices in the filtration order, with [filtration value]:" << std::endl; @@ -249,7 +249,7 @@ BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) { const int DIMENSION_1 = 1; Simplex_tree st; - BOOST_CHECK(rips_complex_from_file.create_complex(st, DIMENSION_1)); + rips_complex_from_file.create_complex(st, DIMENSION_1); std::cout << "st.dimension()=" << st.dimension() << std::endl; BOOST_CHECK(st.dimension() == DIMENSION_1); @@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) { const int DIMENSION_2 = 2; Simplex_tree st2; - BOOST_CHECK(rips_complex_from_file.create_complex(st2, DIMENSION_2)); + rips_complex_from_file.create_complex(st2, DIMENSION_2); std::cout << "st2.dimension()=" << st2.dimension() << std::endl; BOOST_CHECK(st2.dimension() == DIMENSION_2); @@ -308,7 +308,7 @@ BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) { const int DIMENSION_3 = 3; Simplex_tree st3; - BOOST_CHECK(rips_complex_from_file.create_complex(st3, DIMENSION_3)); + rips_complex_from_file.create_complex(st3, DIMENSION_3); std::cout << "st3.dimension()=" << st3.dimension() << std::endl; BOOST_CHECK(st3.dimension() == DIMENSION_3); @@ -327,3 +327,27 @@ BOOST_AUTO_TEST_CASE(Rips_doc_csv_file) { BOOST_CHECK(are_almost_the_same(f0123, std::max(f012, std::max(f123, std::max(f013, f023))))); } + +#ifdef GUDHI_DEBUG +BOOST_AUTO_TEST_CASE(Rips_create_complex_throw) { + // ---------------------------------------------------------------------------- + // + // Init of a rips complex from a OFF file + // + // ---------------------------------------------------------------------------- + std::string off_file_name("alphacomplexdoc.off"); + double rips_threshold = 12.0; + std::cout << "========== OFF FILE NAME = " << off_file_name << " - rips threshold=" << + rips_threshold << "==========" << std::endl; + + Gudhi::Points_off_reader off_reader(off_file_name); + Rips_complex rips_complex_from_file(off_reader.get_point_cloud(), rips_threshold, Euclidean_distance()); + + Simplex_tree stree; + std::vector simplex = {0, 1, 2}; + stree.insert_simplex_and_subfaces(simplex); + std::cout << "Check exception throw in debug mode" << std::endl; + // throw excpt because stree is not empty + BOOST_CHECK_THROW (rips_complex_from_file.create_complex(stree, 1), std::invalid_argument); +} +#endif -- cgit v1.2.3