58 const std::size_t n = m_points.dim(0);
65 std::vector<std::vector<std::int32_t>> &adj = out.
rows;
67 const std::size_t d = m_points.dim(1);
68 std::size_t adjReserveFloor = 16;
79 const auto reserveRows = [&](std::size_t lo, std::size_t hi) {
80 for (std::size_t i = lo; i < hi; ++i) {
81 adj[i].reserve(adjReserveFloor);
91 const T radiusSq = radius * radius;
95 auto emit = [&adj](std::size_t row, std::size_t col) {
96 adj[row].push_back(
static_cast<std::int32_t
>(col));
105 std::vector<std::vector<std::uint32_t>> workerCounts(workers);
106 const auto countRange = [&](std::size_t lo, std::size_t hi) {
108 if (counts.empty()) {
111 for (std::size_t i = lo; i < hi; ++i) {
112 for (
const std::int32_t neighbor : adj[i]) {
113 const auto j =
static_cast<std::size_t
>(neighbor);
120 std::vector<std::uint32_t> mirrorDeg(n, 0);
121 const auto reduceRange = [&](std::size_t lo, std::size_t hi) {
122 for (
const std::vector<std::uint32_t> &counts : workerCounts) {
123 if (counts.empty()) {
126 for (std::size_t i = lo; i < hi; ++i) {
127 mirrorDeg[i] += counts[i];
131 const auto flagRange = [&](std::size_t lo, std::size_t hi) {
132 for (std::size_t i = lo; i < hi; ++i) {
134 (adj[i].size() + mirrorDeg[i] >= minPts) ? std::uint8_t{1} : std::uint8_t{0};
150 std::vector<std::vector<std::pair<std::int32_t, std::int32_t>>> workerMirrors(workers);
151 const auto collectRange = [&](std::size_t lo, std::size_t hi) {
152 std::vector<std::pair<std::int32_t, std::int32_t>> &mirrors =
154 for (std::size_t i = lo; i < hi; ++i) {
155 for (
const std::int32_t neighbor : adj[i]) {
156 const auto j =
static_cast<std::size_t
>(neighbor);
157 if (j > i && out.
isCore[j] == 0) {
158 mirrors.emplace_back(
static_cast<std::int32_t
>(j),
static_cast<std::int32_t
>(i));
168 std::vector<std::pair<std::int32_t, std::int32_t>> mirrors;
169 for (
const auto &local : workerMirrors) {
170 mirrors.insert(mirrors.end(), local.begin(), local.end());
172 std::sort(mirrors.begin(), mirrors.end());
173 for (
const auto &[dest, src] : mirrors) {
174 adj[
static_cast<std::size_t
>(dest)].push_back(src);