87void compute(Index_ num_obs, GetNeighbors_ get_neighbors, GetIndex_ get_index, GetMaxDistance_ get_max_distance,
const Options& options, std::vector<Index_>& selected) {
88 typedef decltype(get_max_distance(0)) Distance_;
90 Payload(Index_ identity, Index_ remaining, Distance_ max_distance) : remaining(remaining), identity(identity), max_distance(max_distance) {}
93 Distance_ max_distance;
96 auto cmp = [](
const Payload& left,
const Payload& right) ->
bool {
97 if (left.remaining == right.remaining) {
98 if (left.max_distance == right.max_distance) {
99 return left.identity > right.identity;
101 return left.max_distance > right.max_distance;
103 return left.remaining < right.remaining;
105 std::priority_queue<Payload, std::vector<Payload>,
decltype(cmp)> store(
108 std::vector<Payload> container;
109 container.reserve(num_obs);
114 std::vector<std::vector<Index_> > reverse_map(num_obs);
115 std::vector<Index_> remaining(num_obs);
116 for (Index_ c = 0; c < num_obs; ++c) {
117 const auto& neighbors = get_neighbors(c);
118 Index_ nneighbors = neighbors.size();
121 store.emplace(c, nneighbors, get_max_distance(c));
122 for (Index_ n = 0; n < nneighbors; ++n) {
123 reverse_map[get_index(neighbors, n)].push_back(c);
125 remaining[c] = nneighbors;
130 std::vector<uint8_t> tainted(num_obs);
132 while (!store.empty()) {
133 auto payload = store.top();
135 if (tainted[payload.identity]) {
139 const auto& neighbors = get_neighbors(payload.identity);
140 Index_ new_remaining = remaining[payload.identity];
142 if (new_remaining >= min_remaining) {
143 payload.remaining = new_remaining;
144 if (!store.empty() && cmp(payload, store.top())) {
147 selected.push_back(payload.identity);
148 tainted[payload.identity] = 1;
149 for (
auto x : reverse_map[payload.identity]) {
153 Index_ nneighbors = neighbors.size();
154 for (Index_ n = 0; n < nneighbors; ++n) {
155 auto current = get_index(neighbors, n);
156 tainted[current] = 1;
157 for (
auto x : reverse_map[current]) {
165 std::sort(selected.begin(), selected.end());
213 throw std::runtime_error(
"number of neighbors is less than 'min_remaining'");
217 std::vector<std::vector<Index_> > nn_indices(nobs);
218 std::vector<Float_> max_distance(nobs);
221 auto sptr = prebuilt.initialize();
222 std::vector<Float_> nn_distances;
223 for (Index_ i = start, end = start + length; i < end; ++i) {
224 sptr->search(i, k, &(nn_indices[i]), &nn_distances);
225 max_distance[i] = (k ? 0 : nn_distances.back());
229 std::vector<Index_> output;
232 [&](
size_t i) ->
const std::vector<Index_>& {
return nn_indices[i]; },
233 [](
const std::vector<Index_>& x, Index_ n) -> Index_ {
return x[n]; },
234 [&](
size_t i) -> Float_ {
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:87