88void compute(Index_ num_obs, GetNeighbors_ get_neighbors, GetIndex_ get_index, GetMaxDistance_ get_max_distance,
const Options& options, std::vector<Index_>& selected) {
89 typedef decltype(get_max_distance(0)) Distance;
91 Payload(Index_ identity, Index_ remaining, Distance max_distance) : remaining(remaining), identity(identity), max_distance(max_distance) {}
94 Distance max_distance;
97 auto cmp = [](
const Payload& left,
const Payload& right) ->
bool {
98 if (left.remaining == right.remaining) {
99 if (left.max_distance == right.max_distance) {
100 return left.identity > right.identity;
102 return left.max_distance > right.max_distance;
104 return left.remaining < right.remaining;
106 std::priority_queue<Payload, std::vector<Payload>,
decltype(cmp)> store(
109 std::vector<Payload> container;
110 container.reserve(num_obs);
115 std::vector<std::vector<Index_> > reverse_map(num_obs);
116 std::vector<Index_> remaining(num_obs);
117 for (Index_ c = 0; c < num_obs; ++c) {
118 const auto& neighbors = get_neighbors(c);
119 Index_ nneighbors = neighbors.size();
122 store.emplace(c, nneighbors, get_max_distance(c));
123 for (Index_ n = 0; n < nneighbors; ++n) {
124 reverse_map[get_index(neighbors, n)].push_back(c);
126 remaining[c] = nneighbors;
131 std::vector<unsigned char> tainted(num_obs);
133 while (!store.empty()) {
134 auto payload = store.top();
136 if (tainted[payload.identity]) {
140 const auto& neighbors = get_neighbors(payload.identity);
141 Index_ new_remaining = remaining[payload.identity];
143 if (new_remaining >= min_remaining) {
144 payload.remaining = new_remaining;
145 if (!store.empty() && cmp(payload, store.top())) {
148 selected.push_back(payload.identity);
149 tainted[payload.identity] = 1;
150 for (
auto x : reverse_map[payload.identity]) {
154 Index_ nneighbors = neighbors.size();
155 for (Index_ n = 0; n < nneighbors; ++n) {
156 auto current = get_index(neighbors, n);
157 tainted[current] = 1;
158 for (
auto x : reverse_map[current]) {
166 std::sort(selected.begin(), selected.end());
216 throw std::runtime_error(
"number of neighbors is less than 'min_remaining'");
221 std::vector<std::vector<Index_> > nn_indices(nobs);
222 std::vector<Distance_> max_distance(nobs);
225 auto sptr = prebuilt.initialize();
226 std::vector<Distance_> nn_distances;
227 for (Index_ i = start, end = start + length; i < end; ++i) {
228 sptr->search(i, capped_k, &(nn_indices[i]), &nn_distances);
229 max_distance[i] = (capped_k ? 0 : nn_distances.back());
233 std::vector<Index_> output;
236 [&](Index_ i) ->
const std::vector<Index_>& {
return nn_indices[i]; },
237 [](
const std::vector<Index_>& x, Index_ n) -> Index_ {
return x[n]; },
238 [&](Index_ i) -> Distance_ {
return max_distance[i]; },
void compute(Index_ num_obs, GetNeighbors_ get_neighbors, GetIndex_ get_index, GetMaxDistance_ get_max_distance, const Options &options, std::vector< Index_ > &selected)
Definition nenesub.hpp:88