diff options
Diffstat (limited to 'src/Subsampling/include/gudhi/choose_n_farthest_points.h')
-rw-r--r-- | src/Subsampling/include/gudhi/choose_n_farthest_points.h | 94 |
1 files changed, 35 insertions, 59 deletions
diff --git a/src/Subsampling/include/gudhi/choose_n_farthest_points.h b/src/Subsampling/include/gudhi/choose_n_farthest_points.h index 5e908090..86500b28 100644 --- a/src/Subsampling/include/gudhi/choose_n_farthest_points.h +++ b/src/Subsampling/include/gudhi/choose_n_farthest_points.h @@ -25,16 +25,9 @@ #include <boost/range.hpp> -#include <gudhi/Kd_tree_search.h> - -#include <gudhi/Clock.h> - -#include <CGAL/Search_traits.h> -#include <CGAL/Search_traits_adapter.h> -#include <CGAL/Fuzzy_sphere.h> +#include <gudhi/Null_output_iterator.h> #include <iterator> -#include <algorithm> // for sort #include <vector> #include <random> #include <limits> // for numeric_limits<> @@ -43,36 +36,51 @@ namespace Gudhi { namespace subsampling { +/** + * \ingroup subsampling + */ +enum : std::size_t { +/** + * Argument for `choose_n_farthest_points` to indicate that the starting point should be picked randomly. + */ + random_starting_point = std::size_t(-1) +}; + /** * \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==random_starting_point`, with a random landmark. * \tparam Kernel must provide a type Kernel::Squared_distance_d which is a model of the * concept <a target="_blank" - * href="http://doc.cgal.org/latest/Kernel_d/classKernel__d_1_1Squared__distance__d.html">Kernel_d::Squared_distance_d</a> - * concept. - * It must also contain a public member 'squared_distance_d_object' of this type. + * href="http://doc.cgal.org/latest/Kernel_d/classKernel__d_1_1Squared__distance__d.html">Kernel_d::Squared_distance_d</a> (despite the name, taken from CGAL, this can be any kind of metric or proximity measure). + * It must also contain a public member `squared_distance_d_object()` that returns an 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 +89,14 @@ void choose_n_farthest_points(Kernel const &k, if (final_size < 1) return; + if (starting_point == random_starting_point) { + // Choose randomly the first landmark + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<std::size_t> 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 +108,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)); @@ -109,47 +126,6 @@ void choose_n_farthest_points(Kernel const &k, } } -/** - * \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 a random landmark. - * \tparam Kernel must provide a type Kernel::Squared_distance_d which is a model of the - * concept <a target="_blank" - * href="http://doc.cgal.org/latest/Kernel_d/classKernel__d_1_1Squared__distance__d.html">Kernel_d::Squared_distance_d</a> - * concept. - * 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`. - * @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[out] output_it The output iterator. - * - */ -template < typename Kernel, -typename Point_range, -typename OutputIterator> -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); -} - } // namespace subsampling } // namespace Gudhi |