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

◆ nearest_neighbor_graph()

MAYAFLUX_API EdgeList MayaFlux::Kinesis::nearest_neighbor_graph ( const Eigen::MatrixXd &  points)

Compute nearest neighbor graph.

Parameters
pointsDxN matrix where each column is a point
Returns
Edge list of nearest neighbor edges

Connects each point to its single nearest neighbor. Directed graph: point i connects to nearest neighbor j, but j may connect to a different point k.

Complexity: O(n²) brute force

Definition at line 457 of file ProximityGraphs.cpp.

458{
459 const auto n = static_cast<size_t>(points.cols());
460 if (n < 2) {
461 return {};
462 }
463
464 const auto dim = static_cast<size_t>(points.rows());
465 const double* base = points.data();
466
467 std::vector<size_t> nearest(n);
468
469 P::for_each(P::par_unseq,
470 std::views::iota(size_t { 0 }, n).begin(),
471 std::views::iota(size_t { 0 }, n).end(),
472 [&](size_t i) {
473 double min_dist_sq = std::numeric_limits<double>::max();
474 size_t best = i;
475
476 const double* pi = base + i * dim;
477 for (size_t j = 0; j < n; ++j) {
478 if (i == j) {
479 continue;
480 }
481 const double d = dist_sq(pi, base + j * dim, dim);
482 if (d < min_dist_sq) {
483 min_dist_sq = d;
484 best = j;
485 }
486 }
487
488 nearest[i] = best;
489 });
490
491 EdgeList edges;
492 edges.reserve(n);
493
494 for (size_t i = 0; i < n; ++i) {
495 if (nearest[i] != i) {
496 edges.emplace_back(i, nearest[i]);
497 }
498 }
499
500 MF_DEBUG(Journal::Component::Kinesis, Journal::Context::Runtime,
501 "nearest_neighbor_graph: {} points, generated {} edges", n, edges.size());
502
503 return edges;
504}
#define MF_DEBUG(comp, ctx,...)
std::vector< glm::vec2 > * points
std::vector< std::pair< size_t, size_t > > EdgeList

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

Referenced by generate_proximity_graph().

+ Here is the caller graph for this function: