small_gicp
knn_result.hpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright 2024 Kenji Koide
2 // SPDX-License-Identifier: MIT
3 #pragma once
4 
5 #include <array>
6 #include <limits>
7 #include <iostream>
8 #include <algorithm>
9 
10 namespace small_gicp {
11 
13 struct KnnSetting {
14 public:
16  template <typename Result>
17  bool fulfilled(const Result& result) const {
18  return result.worst_distance() < epsilon;
19  }
20 
21 public:
22  double epsilon = 0.0;
23 };
24 
27  size_t operator()(size_t i) const { return i; }
28 };
29 
32 template <int N, typename IndexTransform = identity_transform>
33 struct KnnResult {
34 public:
35  static constexpr size_t INVALID = std::numeric_limits<size_t>::max();
36 
41  explicit KnnResult(size_t* indices, double* distances, int num_neighbors = -1, const IndexTransform& index_transform = identity_transform())
43  capacity(num_neighbors),
47  if constexpr (N > 0) {
48  if (num_neighbors >= 0) {
49  std::cerr << "warning: Specifying dynamic num_neighbors=" << num_neighbors << " for a static KNN result container (N=" << N << ")" << std::endl;
50  abort();
51  }
52  } else {
53  if (num_neighbors <= 0) {
54  std::cerr << "error: Specifying invalid num_neighbors=" << num_neighbors << " for a dynamic KNN result container" << std::endl;
55  abort();
56  }
57  }
58 
59  std::fill(this->indices, this->indices + buffer_size(), INVALID);
60  std::fill(this->distances, this->distances + buffer_size(), std::numeric_limits<double>::max());
61  }
62 
64  size_t buffer_size() const {
65  if constexpr (N > 0) {
66  return N;
67  } else {
68  return capacity;
69  }
70  }
71 
73  size_t num_found() const { return num_found_neighbors; }
74 
76  double worst_distance() const { return distances[buffer_size() - 1]; }
77 
80  void push(size_t index, double distance) {
81  if (distance >= worst_distance()) {
82  return;
83  }
84 
85  if constexpr (N == 1) {
86  indices[0] = index_transform(index);
87  distances[0] = distance;
88  } else {
89  int insert_loc = std::min<int>(num_found_neighbors, buffer_size() - 1);
90  for (; insert_loc > 0 && distance < distances[insert_loc - 1]; insert_loc--) {
91  indices[insert_loc] = indices[insert_loc - 1];
92  distances[insert_loc] = distances[insert_loc - 1];
93  }
94 
95  indices[insert_loc] = index_transform(index);
96  distances[insert_loc] = distance;
97  }
98 
99  num_found_neighbors = std::min<int>(num_found_neighbors + 1, buffer_size());
100  }
101 
102 public:
103  const IndexTransform index_transform;
104  const int capacity;
106  size_t* indices;
107  double* distances;
108 };
109 
110 } // namespace small_gicp
Definition: flat_container.hpp:12
K-nearest neighbor search result container.
Definition: knn_result.hpp:33
double worst_distance() const
Worst distance in the result.
Definition: knn_result.hpp:76
size_t buffer_size() const
Buffer size (i.e., Maximum number of neighbors)
Definition: knn_result.hpp:64
const IndexTransform index_transform
Point index transformation (e.g., local point index to global point/voxel index)
Definition: knn_result.hpp:103
double * distances
Distances to neighbors.
Definition: knn_result.hpp:107
static constexpr size_t INVALID
Definition: knn_result.hpp:35
const int capacity
Maximum number of neighbors to search.
Definition: knn_result.hpp:104
void push(size_t index, double distance)
Push a pair of point index and distance to the result.
Definition: knn_result.hpp:80
size_t num_found() const
Number of found neighbors.
Definition: knn_result.hpp:73
KnnResult(size_t *indices, double *distances, int num_neighbors=-1, const IndexTransform &index_transform=identity_transform())
Constructor.
Definition: knn_result.hpp:41
size_t * indices
Indices of neighbors.
Definition: knn_result.hpp:106
int num_found_neighbors
Number of found neighbors.
Definition: knn_result.hpp:105
K-nearest neighbor search setting.
Definition: knn_result.hpp:13
double epsilon
Early termination threshold.
Definition: knn_result.hpp:22
bool fulfilled(const Result &result) const
Check if the result satisfies the early termination condition.
Definition: knn_result.hpp:17
Identity transform (alternative to std::identity in C++20).
Definition: knn_result.hpp:26
size_t operator()(size_t i) const
Definition: knn_result.hpp:27