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

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