106void compute(
const Index_ num_obs,
const GetNeighbors_ get_neighbors,
const GetIndex_ get_index,
const GetMaxDistance_ get_max_distance,
const Options& options, std::vector<Index_>& selected) {
107 typedef decltype(I(get_max_distance(0))) Distance;
109 Payload(
const Index_ identity,
const Index_ remaining,
const Distance max_distance) : remaining(remaining), identity(identity), max_distance(max_distance) {}
112 Distance max_distance;
115 const auto cmp = [](
const Payload& left,
const Payload& right) ->
bool {
116 if (left.remaining == right.remaining) {
117 if (left.max_distance == right.max_distance) {
118 return left.identity > right.identity;
120 return left.max_distance > right.max_distance;
122 return left.remaining < right.remaining;
124 std::priority_queue<Payload, std::vector<Payload>,
decltype(I(cmp))> store(
127 std::vector<Payload> container;
128 container.reserve(num_obs);
133 auto reverse_map = sanisizer::create<std::vector<std::vector<Index_> > >(num_obs);
134 auto remaining = sanisizer::create<std::vector<Index_> >(num_obs);
135 for (Index_ c = 0; c < num_obs; ++c) {
136 const auto& neighbors = get_neighbors(c);
137 const Index_ nneighbors = neighbors.size();
140 store.emplace(c, nneighbors, get_max_distance(c));
141 for (Index_ n = 0; n < nneighbors; ++n) {
142 reverse_map[get_index(neighbors, n)].push_back(c);
144 remaining[c] = nneighbors;
149 auto tainted = sanisizer::create<std::vector<unsigned char> >(num_obs);
151 while (!store.empty()) {
152 auto payload = store.top();
154 if (tainted[payload.identity]) {
158 const Index_ new_remaining = remaining[payload.identity];
159 if (new_remaining < min_remaining) {
163 payload.remaining = new_remaining;
164 if (!store.empty() && cmp(payload, store.top())) {
169 selected.push_back(payload.identity);
170 tainted[payload.identity] = 1;
171 for (
const auto x : reverse_map[payload.identity]) {
175 const auto& neighbors = get_neighbors(payload.identity);
176 const Index_ nneighbors = neighbors.size();
177 for (Index_ n = 0; n < nneighbors; ++n) {
178 const auto current = get_index(neighbors, n);
179 if (tainted[current]) {
182 tainted[current] = 1;
183 for (
const auto x : reverse_map[current]) {
189 std::sort(selected.begin(), selected.end());
208 std::vector<Index_> output;
210 static_cast<Index_
>(neighbors.size()),
211 [&](
const Index_ i) ->
const auto& { return neighbors[i]; },
212 [](
const std::vector<std::pair<Index_, Distance_> >& x,
const Index_ n) -> Index_ { return x[n].first; },
213 [&](
const Index_ i) -> Distance_ { return neighbors[i].back().second; },
238 throw std::runtime_error(
"number of neighbors is less than 'min_remaining'");
243 auto nn_indices = sanisizer::create<std::vector<std::vector<Index_> > >(nobs);
244 auto max_distance = sanisizer::create<std::vector<Distance_> >(nobs);
247 const auto sptr = prebuilt.initialize();
248 std::vector<Distance_> nn_distances;
249 for (Index_ i = start, end = start + length; i < end; ++i) {
250 sptr->search(i, capped_k, &(nn_indices[i]), &nn_distances);
251 max_distance[i] = (capped_k ? nn_distances.back() : 0);
255 std::vector<Index_> output;
258 [&](
const Index_ i) ->
const std::vector<Index_>& {
return nn_indices[i]; },
259 [](
const std::vector<Index_>& x,
const Index_ n) -> Index_ {
return x[n]; },
260 [&](
const Index_ i) -> Distance_ {
return max_distance[i]; },
void compute(const Index_ num_obs, const GetNeighbors_ get_neighbors, const GetIndex_ get_index, const GetMaxDistance_ get_max_distance, const Options &options, std::vector< Index_ > &selected)
Definition nenesub.hpp:106