MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ k_nearest_neighbors()

MAYAFLUX_API EdgeList MayaFlux::Kinesis::k_nearest_neighbors ( const Eigen::MatrixXd &  points,
size_t  k 
)

Compute K-nearest neighbors graph.

Parameters
pointsDx N matrix where each column is a point
kNumber of nearest neighbors per point
Returns
Edge list (point index pairs)

For each point, connects it to its k nearest neighbors. Directed graph: point i connects to k neighbors, but neighbor j might not reciprocally connect to i.

Complexity: O(n² log k) with partial sort

Definition at line 256 of file ProximityGraphs.cpp.

259{
260 const auto n = static_cast<size_t>(points.cols());
261 if (n < 2) {
262 return {};
263 }
264
265 k = std::min(k, n - 1);
266 if (k == 0) {
267 return {};
268 }
269
270 const auto dim = static_cast<size_t>(points.rows());
271 const double* base = points.data();
272
273 EdgeList edges(n * k);
274
275 P::for_each(P::par_unseq,
276 std::views::iota(size_t { 0 }, n).begin(),
277 std::views::iota(size_t { 0 }, n).end(),
278 [&](size_t i) {
279 std::vector<std::pair<double, size_t>> distances;
280 distances.reserve(n - 1);
281
282 const double* pi = base + i * dim;
283 for (size_t j = 0; j < n; ++j) {
284 if (i == j) {
285 continue;
286 }
287 distances.emplace_back(dist_sq(pi, base + j * dim, dim), j);
288 }
289
290 std::partial_sort(
291 distances.begin(),
292 distances.begin() + static_cast<ptrdiff_t>(k),
293 distances.end());
294
295 for (size_t m = 0; m < k; ++m) {
296 edges[i * k + m] = { i, distances[m].second };
297 }
298 });
299
300 MF_DEBUG(Journal::Component::Kinesis, Journal::Context::Runtime,
301 "k_nearest_neighbors: {} points, k={}, generated {} edges",
302 n, k, edges.size());
303
304 return edges;
305}
#define MF_DEBUG(comp, ctx,...)
std::vector< glm::vec2 > * points
float k
std::vector< std::pair< size_t, size_t > > EdgeList

References k, MayaFlux::Journal::Kinesis, MF_DEBUG, points, and MayaFlux::Journal::Runtime.

Referenced by generate_proximity_graph().

+ Here is the caller graph for this function: