summaryrefslogtreecommitdiff
path: root/src/Subsampling/include/gudhi/choose_n_farthest_points.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/Subsampling/include/gudhi/choose_n_farthest_points.h')
-rw-r--r--src/Subsampling/include/gudhi/choose_n_farthest_points.h94
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