From b0859ffb8c5d030f3d37ba758a325250f1d1c982 Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 24 Feb 2017 14:23:48 +0000 Subject: Let choose_n_farthest_points output distances (optional). Drop unused CGAL includes. git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@2105 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: c5a34492a451c8455c42eb8db1c6c7ca5f1bc7b2 --- .../include/gudhi/choose_n_farthest_points.h | 57 +++++++++++----------- .../test/test_choose_n_farthest_points.cpp | 43 ++++++++++------ src/common/include/gudhi/Null_output_iterator.h | 48 ++++++++++++++++++ 3 files changed, 103 insertions(+), 45 deletions(-) create mode 100644 src/common/include/gudhi/Null_output_iterator.h diff --git a/src/Subsampling/include/gudhi/choose_n_farthest_points.h b/src/Subsampling/include/gudhi/choose_n_farthest_points.h index 5e908090..a77d0cd7 100644 --- a/src/Subsampling/include/gudhi/choose_n_farthest_points.h +++ b/src/Subsampling/include/gudhi/choose_n_farthest_points.h @@ -25,16 +25,10 @@ #include -#include - +#include #include -#include -#include -#include - #include -#include // for sort #include #include #include // for numeric_limits<> @@ -47,7 +41,7 @@ namespace subsampling { * \ingroup subsampling * \brief Subsample by a greedy strategy of iteratively adding the farthest point from the * current chosen point set to the subsampling. - * The iteration starts with the landmark `starting point`. + * The iteration starts with the landmark `starting point` or, if `starting point==-1`, with a random landmark. * \tparam Kernel must provide a type Kernel::Squared_distance_d which is a model of the * concept Kernel_d::Squared_distance_d @@ -55,24 +49,30 @@ namespace subsampling { * It must also contain a public member 'squared_distance_d_object' of this type. * \tparam Point_range Range whose value type is Kernel::Point_d. It must provide random-access * via `operator[]` and the points should be stored contiguously in memory. - * \tparam OutputIterator Output iterator whose value type is Kernel::Point_d. - * \details It chooses `final_size` points from a random access range `input_pts` and - * outputs it in the output iterator `output_it`. + * \tparam PointOutputIterator Output iterator whose value type is Kernel::Point_d. + * \tparam DistanceOutputIterator Output iterator for distances. + * \details It chooses `final_size` points from a random access range + * `input_pts` and outputs them in the output iterator `output_it`. It also + * outputs the distance from each of those points to the set of previous + * points in `dist_it`. * @param[in] k A kernel object. * @param[in] input_pts Const reference to the input points. * @param[in] final_size The size of the subsample to compute. * @param[in] starting_point The seed in the farthest point algorithm. - * @param[out] output_it The output iterator. + * @param[out] output_it The output iterator for points. + * @param[out] dist_it The optional output iterator for distances. * */ template < typename Kernel, typename Point_range, -typename OutputIterator> +typename PointOutputIterator, +typename DistanceOutputIterator=Null_output_iterator> void choose_n_farthest_points(Kernel const &k, Point_range const &input_pts, std::size_t final_size, std::size_t starting_point, - OutputIterator output_it) { + PointOutputIterator output_it, + DistanceOutputIterator dist_it={}) { std::size_t nb_points = boost::size(input_pts); if (final_size > nb_points) final_size = nb_points; @@ -81,6 +81,14 @@ void choose_n_farthest_points(Kernel const &k, if (final_size < 1) return; + if (starting_point == std::size_t(-1)) { + // Choose randomly the first landmark + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution dis(0, (input_pts.size() - 1)); + starting_point = dis(gen); + } + typename Kernel::Squared_distance_d sqdist = k.squared_distance_d_object(); std::size_t current_number_of_landmarks = 0; // counter for landmarks @@ -92,6 +100,7 @@ void choose_n_farthest_points(Kernel const &k, for (current_number_of_landmarks = 0; current_number_of_landmarks != final_size; current_number_of_landmarks++) { // curr_max_w at this point is the next landmark *output_it++ = input_pts[curr_max_w]; + *dist_it++ = dist_to_L[curr_max_w]; std::size_t i = 0; for (auto& p : input_pts) { double curr_dist = sqdist(p, *(std::begin(input_pts) + curr_max_w)); @@ -121,7 +130,7 @@ void choose_n_farthest_points(Kernel const &k, * It must also contain a public member 'squared_distance_d_object' of this type. * \tparam Point_range Range whose value type is Kernel::Point_d. It must provide random-access * via `operator[]` and the points should be stored contiguously in memory. - * \tparam OutputIterator Output iterator whose value type is Kernel::Point_d. + * \tparam PointOutputIterator Output iterator whose value type is Kernel::Point_d. * \details It chooses `final_size` points from a random access range `input_pts` and * outputs it in the output iterator `output_it`. * @param[in] k A kernel object. @@ -132,22 +141,12 @@ void choose_n_farthest_points(Kernel const &k, */ template < typename Kernel, typename Point_range, -typename OutputIterator> +typename PointOutputIterator> void choose_n_farthest_points(Kernel const& k, Point_range const &input_pts, - unsigned final_size, - OutputIterator output_it) { - // Tests to the limit - if ((final_size < 1) || (input_pts.size() == 0)) - return; - - // Choose randomly the first landmark - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution<> dis(0, (input_pts.size() - 1)); - std::size_t starting_point = dis(gen); - - choose_n_farthest_points(k, input_pts, final_size, starting_point, output_it); + std::size_t final_size, + PointOutputIterator output_it) { + choose_n_farthest_points(k, input_pts, final_size, -1, output_it); } } // namespace subsampling diff --git a/src/Subsampling/test/test_choose_n_farthest_points.cpp b/src/Subsampling/test/test_choose_n_farthest_points.cpp index 0bc0dff4..6bc5f7b0 100644 --- a/src/Subsampling/test/test_choose_n_farthest_points.cpp +++ b/src/Subsampling/test/test_choose_n_farthest_points.cpp @@ -70,34 +70,45 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_choose_farthest_point_limits, Kernel, list_of typedef typename Kernel::FT FT; typedef typename Kernel::Point_d Point_d; std::vector< Point_d > points, landmarks; + std::vector< FT > distances; landmarks.clear(); Kernel k; // Choose -1 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, -1, std::back_inserter(landmarks)); + Gudhi::subsampling::choose_n_farthest_points(k, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); + landmarks.clear(); distances.clear(); // Choose 0 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 0, std::back_inserter(landmarks)); + Gudhi::subsampling::choose_n_farthest_points(k, points, 0, -1, std::back_inserter(landmarks), std::back_inserter(distances)); BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); + landmarks.clear(); distances.clear(); // Choose 1 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 1, std::back_inserter(landmarks)); + Gudhi::subsampling::choose_n_farthest_points(k, points, 1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); + landmarks.clear(); distances.clear(); std::vector point({0.0, 0.0, 0.0, 0.0}); points.push_back(Point_d(point.begin(), point.end())); - // Choose -1 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, -1, std::back_inserter(landmarks)); - BOOST_CHECK(landmarks.size() == 1); - landmarks.clear(); + // Choose -1 farthest points in a one point cloud + Gudhi::subsampling::choose_n_farthest_points(k, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + BOOST_CHECK(landmarks.size() == 1 && distances.size() == 1); + BOOST_CHECK(distances[0] == std::numeric_limits::infinity()); + landmarks.clear(); distances.clear(); // Choose 0 farthest points in a one point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 0, std::back_inserter(landmarks)); - BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); + Gudhi::subsampling::choose_n_farthest_points(k, points, 0, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + BOOST_CHECK(landmarks.size() == 0 && distances.size() == 0); + landmarks.clear(); distances.clear(); // Choose 1 farthest points in a one point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 1, std::back_inserter(landmarks)); - BOOST_CHECK(landmarks.size() == 1); - landmarks.clear(); + Gudhi::subsampling::choose_n_farthest_points(k, points, 1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + BOOST_CHECK(landmarks.size() == 1 && distances.size() == 1); + BOOST_CHECK(distances[0] == std::numeric_limits::infinity()); + landmarks.clear(); distances.clear(); + std::vector point2({1.0, 0.0, 0.0, 0.0}); + points.push_back(Point_d(point2.begin(), point2.end())); + // Choose all farthest points in a one point cloud + Gudhi::subsampling::choose_n_farthest_points(k, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + BOOST_CHECK(landmarks.size() == 2 && distances.size() == 2); + BOOST_CHECK(distances[0] == std::numeric_limits::infinity()); + BOOST_CHECK(distances[1] == 1); + landmarks.clear(); distances.clear(); } diff --git a/src/common/include/gudhi/Null_output_iterator.h b/src/common/include/gudhi/Null_output_iterator.h new file mode 100644 index 00000000..0cf043cd --- /dev/null +++ b/src/common/include/gudhi/Null_output_iterator.h @@ -0,0 +1,48 @@ +/* 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): Marc Glisse + * + * Copyright (C) 2017 INRIA + * + * 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 . + */ + +#ifndef NULL_OUTPUT_ITERATOR_H_ +#define NULL_OUTPUT_ITERATOR_H_ + +#include + +namespace Gudhi { + +/** An output iterator that ignores whatever it is given. */ +struct Null_output_iterator { + typedef std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + Null_output_iterator& operator++(){return *this;} + Null_output_iterator operator++(int){return *this;} + struct proxy { + template + proxy& operator=(T&&){return *this;} + }; + proxy operator*()const{return {};} +}; +} // namespace Gudhi + +#endif // NULL_OUTPUT_ITERATOR_H_ -- cgit v1.2.3 From 18a13841ce995148b0c46a35ee9209626f6bf3d5 Mon Sep 17 00:00:00 2001 From: glisse Date: Fri, 24 Feb 2017 14:28:24 +0000 Subject: Revert previous commit, was supposed to go to a branch !!! git-svn-id: svn+ssh://scm.gforge.inria.fr/svnroot/gudhi/trunk@2106 636b058d-ea47-450e-bf9e-a15bfbe3eedb Former-commit-id: 59183c46120a19ad0a840dd57b7a4706a4d44bdd --- .../include/gudhi/choose_n_farthest_points.h | 57 +++++++++++----------- .../test/test_choose_n_farthest_points.cpp | 43 ++++++---------- src/common/include/gudhi/Null_output_iterator.h | 48 ------------------ 3 files changed, 45 insertions(+), 103 deletions(-) delete mode 100644 src/common/include/gudhi/Null_output_iterator.h diff --git a/src/Subsampling/include/gudhi/choose_n_farthest_points.h b/src/Subsampling/include/gudhi/choose_n_farthest_points.h index a77d0cd7..5e908090 100644 --- a/src/Subsampling/include/gudhi/choose_n_farthest_points.h +++ b/src/Subsampling/include/gudhi/choose_n_farthest_points.h @@ -25,10 +25,16 @@ #include -#include +#include + #include +#include +#include +#include + #include +#include // for sort #include #include #include // for numeric_limits<> @@ -41,7 +47,7 @@ namespace subsampling { * \ingroup subsampling * \brief Subsample by a greedy strategy of iteratively adding the farthest point from the * current chosen point set to the subsampling. - * The iteration starts with the landmark `starting point` or, if `starting point==-1`, with a random landmark. + * The iteration starts with the landmark `starting point`. * \tparam Kernel must provide a type Kernel::Squared_distance_d which is a model of the * concept Kernel_d::Squared_distance_d @@ -49,30 +55,24 @@ namespace subsampling { * It must also contain a public member 'squared_distance_d_object' of this type. * \tparam Point_range Range whose value type is Kernel::Point_d. It must provide random-access * via `operator[]` and the points should be stored contiguously in memory. - * \tparam PointOutputIterator Output iterator whose value type is Kernel::Point_d. - * \tparam DistanceOutputIterator Output iterator for distances. - * \details It chooses `final_size` points from a random access range - * `input_pts` and outputs them in the output iterator `output_it`. It also - * outputs the distance from each of those points to the set of previous - * points in `dist_it`. + * \tparam OutputIterator Output iterator whose value type is Kernel::Point_d. + * \details It chooses `final_size` points from a random access range `input_pts` and + * outputs it in the output iterator `output_it`. * @param[in] k A kernel object. * @param[in] input_pts Const reference to the input points. * @param[in] final_size The size of the subsample to compute. * @param[in] starting_point The seed in the farthest point algorithm. - * @param[out] output_it The output iterator for points. - * @param[out] dist_it The optional output iterator for distances. + * @param[out] output_it The output iterator. * */ template < typename Kernel, typename Point_range, -typename PointOutputIterator, -typename DistanceOutputIterator=Null_output_iterator> +typename OutputIterator> void choose_n_farthest_points(Kernel const &k, Point_range const &input_pts, std::size_t final_size, std::size_t starting_point, - PointOutputIterator output_it, - DistanceOutputIterator dist_it={}) { + OutputIterator output_it) { std::size_t nb_points = boost::size(input_pts); if (final_size > nb_points) final_size = nb_points; @@ -81,14 +81,6 @@ void choose_n_farthest_points(Kernel const &k, if (final_size < 1) return; - if (starting_point == std::size_t(-1)) { - // Choose randomly the first landmark - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution dis(0, (input_pts.size() - 1)); - starting_point = dis(gen); - } - typename Kernel::Squared_distance_d sqdist = k.squared_distance_d_object(); std::size_t current_number_of_landmarks = 0; // counter for landmarks @@ -100,7 +92,6 @@ void choose_n_farthest_points(Kernel const &k, for (current_number_of_landmarks = 0; current_number_of_landmarks != final_size; current_number_of_landmarks++) { // curr_max_w at this point is the next landmark *output_it++ = input_pts[curr_max_w]; - *dist_it++ = dist_to_L[curr_max_w]; std::size_t i = 0; for (auto& p : input_pts) { double curr_dist = sqdist(p, *(std::begin(input_pts) + curr_max_w)); @@ -130,7 +121,7 @@ void choose_n_farthest_points(Kernel const &k, * It must also contain a public member 'squared_distance_d_object' of this type. * \tparam Point_range Range whose value type is Kernel::Point_d. It must provide random-access * via `operator[]` and the points should be stored contiguously in memory. - * \tparam PointOutputIterator Output iterator whose value type is Kernel::Point_d. + * \tparam OutputIterator Output iterator whose value type is Kernel::Point_d. * \details It chooses `final_size` points from a random access range `input_pts` and * outputs it in the output iterator `output_it`. * @param[in] k A kernel object. @@ -141,12 +132,22 @@ void choose_n_farthest_points(Kernel const &k, */ template < typename Kernel, typename Point_range, -typename PointOutputIterator> +typename OutputIterator> void choose_n_farthest_points(Kernel const& k, Point_range const &input_pts, - std::size_t final_size, - PointOutputIterator output_it) { - choose_n_farthest_points(k, input_pts, final_size, -1, output_it); + unsigned final_size, + OutputIterator output_it) { + // Tests to the limit + if ((final_size < 1) || (input_pts.size() == 0)) + return; + + // Choose randomly the first landmark + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(0, (input_pts.size() - 1)); + std::size_t starting_point = dis(gen); + + choose_n_farthest_points(k, input_pts, final_size, starting_point, output_it); } } // namespace subsampling diff --git a/src/Subsampling/test/test_choose_n_farthest_points.cpp b/src/Subsampling/test/test_choose_n_farthest_points.cpp index 6bc5f7b0..0bc0dff4 100644 --- a/src/Subsampling/test/test_choose_n_farthest_points.cpp +++ b/src/Subsampling/test/test_choose_n_farthest_points.cpp @@ -70,45 +70,34 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_choose_farthest_point_limits, Kernel, list_of typedef typename Kernel::FT FT; typedef typename Kernel::Point_d Point_d; std::vector< Point_d > points, landmarks; - std::vector< FT > distances; landmarks.clear(); Kernel k; // Choose -1 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + Gudhi::subsampling::choose_n_farthest_points(k, points, -1, std::back_inserter(landmarks)); BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); distances.clear(); + landmarks.clear(); // Choose 0 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 0, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + Gudhi::subsampling::choose_n_farthest_points(k, points, 0, std::back_inserter(landmarks)); BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); distances.clear(); + landmarks.clear(); // Choose 1 farthest points in an empty point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); + Gudhi::subsampling::choose_n_farthest_points(k, points, 1, std::back_inserter(landmarks)); BOOST_CHECK(landmarks.size() == 0); - landmarks.clear(); distances.clear(); + landmarks.clear(); std::vector point({0.0, 0.0, 0.0, 0.0}); points.push_back(Point_d(point.begin(), point.end())); - // Choose -1 farthest points in a one point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); - BOOST_CHECK(landmarks.size() == 1 && distances.size() == 1); - BOOST_CHECK(distances[0] == std::numeric_limits::infinity()); - landmarks.clear(); distances.clear(); + // Choose -1 farthest points in an empty point cloud + Gudhi::subsampling::choose_n_farthest_points(k, points, -1, std::back_inserter(landmarks)); + BOOST_CHECK(landmarks.size() == 1); + landmarks.clear(); // Choose 0 farthest points in a one point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 0, -1, std::back_inserter(landmarks), std::back_inserter(distances)); - BOOST_CHECK(landmarks.size() == 0 && distances.size() == 0); - landmarks.clear(); distances.clear(); + Gudhi::subsampling::choose_n_farthest_points(k, points, 0, std::back_inserter(landmarks)); + BOOST_CHECK(landmarks.size() == 0); + landmarks.clear(); // Choose 1 farthest points in a one point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, 1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); - BOOST_CHECK(landmarks.size() == 1 && distances.size() == 1); - BOOST_CHECK(distances[0] == std::numeric_limits::infinity()); - landmarks.clear(); distances.clear(); + Gudhi::subsampling::choose_n_farthest_points(k, points, 1, std::back_inserter(landmarks)); + BOOST_CHECK(landmarks.size() == 1); + landmarks.clear(); - std::vector point2({1.0, 0.0, 0.0, 0.0}); - points.push_back(Point_d(point2.begin(), point2.end())); - // Choose all farthest points in a one point cloud - Gudhi::subsampling::choose_n_farthest_points(k, points, -1, -1, std::back_inserter(landmarks), std::back_inserter(distances)); - BOOST_CHECK(landmarks.size() == 2 && distances.size() == 2); - BOOST_CHECK(distances[0] == std::numeric_limits::infinity()); - BOOST_CHECK(distances[1] == 1); - landmarks.clear(); distances.clear(); } diff --git a/src/common/include/gudhi/Null_output_iterator.h b/src/common/include/gudhi/Null_output_iterator.h deleted file mode 100644 index 0cf043cd..00000000 --- a/src/common/include/gudhi/Null_output_iterator.h +++ /dev/null @@ -1,48 +0,0 @@ -/* 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): Marc Glisse - * - * Copyright (C) 2017 INRIA - * - * 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 . - */ - -#ifndef NULL_OUTPUT_ITERATOR_H_ -#define NULL_OUTPUT_ITERATOR_H_ - -#include - -namespace Gudhi { - -/** An output iterator that ignores whatever it is given. */ -struct Null_output_iterator { - typedef std::output_iterator_tag iterator_category; - typedef void value_type; - typedef void difference_type; - typedef void pointer; - typedef void reference; - - Null_output_iterator& operator++(){return *this;} - Null_output_iterator operator++(int){return *this;} - struct proxy { - template - proxy& operator=(T&&){return *this;} - }; - proxy operator*()const{return {};} -}; -} // namespace Gudhi - -#endif // NULL_OUTPUT_ITERATOR_H_ -- cgit v1.2.3