MayaFlux 1.0.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 455 of file ProximityGraphs.cpp.

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