64 const std::size_t n = X.
dim(0);
69 out.
edges.reserve(n - 1);
83 const auto kSigned =
static_cast<std::int32_t
>(minSamples);
84 auto [knnIdx, knnSqDist] = tree.knnQuery(kSigned, pool);
86 for (std::size_t i = 0; i < n; ++i) {
87 coreDistData[i] = knnSqDist(i, minSamples - 1);
95 std::vector<std::int32_t> componentOf(n, std::int32_t{0});
96 std::vector<detail::ComponentBestEdge<T>> bestPerComponent(n);
97 std::vector<std::int32_t> activeRoots;
98 activeRoots.reserve(n);
100 bool firstRound =
true;
102 for (std::size_t i = 0; i < n; ++i) {
103 componentOf[i] =
static_cast<std::int32_t
>(uf.
find(
static_cast<std::uint32_t
>(i)));
108 detail::nearestOutComponent<T>(tree, std::span<const std::int32_t>(componentOf),
109 out.
coreDistances, knnIdx, knnSqDist, pool, bestPerComponent,
118 for (std::size_t i = 0; i < n; ++i) {
119 if (std::cmp_equal(componentOf[i], i)) {
120 activeRoots.push_back(
static_cast<std::int32_t
>(i));
126 std::sort(activeRoots.begin(), activeRoots.end(),
127 [&](std::int32_t a, std::int32_t b)
noexcept {
128 const auto &ea = bestPerComponent[static_cast<std::size_t>(a)];
129 const auto &eb = bestPerComponent[static_cast<std::size_t>(b)];
130 if (ea.weight != eb.weight) {
131 return ea.weight < eb.weight;
139 bool unitedAny =
false;
140 for (
const std::int32_t c : activeRoots) {
141 const auto &edge = bestPerComponent[
static_cast<std::size_t
>(c)];
143 if (uf.
unite(
static_cast<std::uint32_t
>(edge.u),
static_cast<std::uint32_t
>(edge.v))) {
161 std::sort(out.edges.begin(), out.edges.end(),
163 if (a.weight != b.weight) {
164 return a.weight < b.weight;