cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
bfknn_impl.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <cmath>
5#include <limits>
6#include <numeric>
7#include <vector>
9
10namespace toolbox::pcl
11{
12
13// Generic brute-force KNN implementation
14template<typename Element, typename Metric>
16{
17 m_data = std::make_shared<container_type>(data);
18 return m_data->size();
19}
20
21template<typename Element, typename Metric>
23{
24 m_data = data;
25 return m_data ? m_data->size() : 0;
26}
27
28template<typename Element, typename Metric>
30{
31 m_compile_time_metric = metric;
32 m_use_runtime_metric = false;
33}
34
35template<typename Element, typename Metric>
36template<typename T>
38 std::shared_ptr<toolbox::metrics::IMetric<T>> metric)
39{
40 // For point types, we need to create an adapter
41 if constexpr (std::is_same_v<Element, toolbox::types::point_t<T>>) {
42 m_runtime_metric = std::make_shared<toolbox::metrics::PointMetricAdapter<T>>(metric);
43 } else {
44 m_runtime_metric = metric;
45 }
46 m_use_runtime_metric = true;
47}
48
49template<typename Element, typename Metric>
50template<typename T>
52 std::unique_ptr<toolbox::metrics::IMetric<T>> metric)
53{
54 // Convert unique_ptr to shared_ptr
55 auto shared_metric = std::shared_ptr<toolbox::metrics::IMetric<T>>(std::move(metric));
56 set_metric_impl(shared_metric);
57}
58
59template<typename Element, typename Metric>
61 const element_type& query,
62 std::size_t num_neighbors,
63 std::vector<std::size_t>& indices,
64 std::vector<distance_type>& distances)
65{
66 if (!m_data || m_data->empty())
67 {
68 return false;
69 }
70
71 const std::size_t data_size = m_data->size();
72 num_neighbors = std::min(num_neighbors, data_size);
73
74 // Compute all distances
75 std::vector<std::pair<distance_type, std::size_t>> distance_index_pairs;
76 distance_index_pairs.reserve(data_size);
77
78 for (std::size_t i = 0; i < data_size; ++i)
79 {
80 distance_type dist;
81 if (m_use_runtime_metric && m_runtime_metric)
82 {
83 if constexpr (std::is_same_v<Element, toolbox::types::point_t<typename Element::value_type>>) {
84 // For point types, convert to arrays and use distance method
85 value_type arr_query[3] = {query.x, query.y, query.z};
86 value_type arr_data[3] = {(*m_data)[i].x, (*m_data)[i].y, (*m_data)[i].z};
87 dist = m_runtime_metric->distance(arr_query, arr_data, 3);
88 } else {
89 // For generic types, assume they have data() and size() methods
90 dist = m_runtime_metric->distance(query, (*m_data)[i]);
91 }
92 }
93 else
94 {
95 dist = m_compile_time_metric(query, (*m_data)[i]);
96 }
97 distance_index_pairs.emplace_back(dist, i);
98 }
99
100 // Partial sort to get k nearest neighbors
101 std::partial_sort(distance_index_pairs.begin(),
102 distance_index_pairs.begin() + num_neighbors,
103 distance_index_pairs.end(),
104 [](const auto& a, const auto& b) { return a.first < b.first; });
105
106 // Extract results
107 indices.resize(num_neighbors);
108 distances.resize(num_neighbors);
109 for (std::size_t i = 0; i < num_neighbors; ++i)
110 {
111 distances[i] = distance_index_pairs[i].first;
112 indices[i] = distance_index_pairs[i].second;
113 }
114
115 return true;
116}
117
118template<typename Element, typename Metric>
120 const element_type& query,
121 distance_type radius,
122 std::vector<std::size_t>& indices,
123 std::vector<distance_type>& distances)
124{
125 if (!m_data || m_data->empty() || radius <= 0)
126 {
127 return false;
128 }
129
130 indices.clear();
131 distances.clear();
132
133 const std::size_t data_size = m_data->size();
134 std::vector<std::pair<distance_type, std::size_t>> distance_index_pairs;
135
136 for (std::size_t i = 0; i < data_size; ++i)
137 {
138 distance_type dist;
139 if (m_use_runtime_metric && m_runtime_metric)
140 {
141 if constexpr (std::is_same_v<Element, toolbox::types::point_t<typename Element::value_type>>) {
142 // For point types, convert to arrays and use distance method
143 value_type arr_query[3] = {query.x, query.y, query.z};
144 value_type arr_data[3] = {(*m_data)[i].x, (*m_data)[i].y, (*m_data)[i].z};
145 dist = m_runtime_metric->distance(arr_query, arr_data, 3);
146 } else {
147 // For generic types, assume they have data() and size() methods
148 dist = m_runtime_metric->distance(query, (*m_data)[i]);
149 }
150 }
151 else
152 {
153 dist = m_compile_time_metric(query, (*m_data)[i]);
154 }
155
156 if (dist <= radius)
157 {
158 distance_index_pairs.emplace_back(dist, i);
159 }
160 }
161
162 // Sort by distance
163 std::sort(distance_index_pairs.begin(), distance_index_pairs.end(),
164 [](const auto& a, const auto& b) { return a.first < b.first; });
165
166 // Extract results
167 indices.reserve(distance_index_pairs.size());
168 distances.reserve(distance_index_pairs.size());
169 for (const auto& [dist, idx] : distance_index_pairs)
170 {
171 distances.push_back(dist);
172 indices.push_back(idx);
173 }
174
175 return true;
176}
177
178} // namespace toolbox::pcl
Definition metric_factory.hpp:23
bool kneighbors_impl(const element_type &query, std::size_t num_neighbors, std::vector< std::size_t > &indices, std::vector< distance_type > &distances)
K近邻搜索的实现 / Implementation of K-nearest neighbors search.
Definition bfknn_impl.hpp:60
typename base_type::container_type container_type
Definition bfknn.hpp:52
typename Element::value_type value_type
Definition bfknn.hpp:54
typename traits_type::element_type element_type
Definition bfknn.hpp:49
typename traits_type::distance_type distance_type
Definition bfknn.hpp:51
std::size_t set_input_impl(const container_type &data)
设置输入数据的实现 / Implementation of setting input data
Definition bfknn_impl.hpp:15
typename traits_type::metric_type metric_type
Definition bfknn.hpp:50
typename base_type::container_ptr container_ptr
Definition bfknn.hpp:53
bool radius_neighbors_impl(const element_type &query, distance_type radius, std::vector< std::size_t > &indices, std::vector< distance_type > &distances)
半径近邻搜索的实现 / Implementation of radius neighbors search
Definition bfknn_impl.hpp:119
void set_metric_impl(const metric_type &metric)
设置度量方式的实现(编译时版本) / Implementation of setting metric (compile-time version)
Definition bfknn_impl.hpp:29
Definition base_correspondence_generator.hpp:18