mnncorrect
Batch correction with mutual nearest neighbors
Loading...
Searching...
No Matches
mnncorrect.hpp
Go to the documentation of this file.
1#ifndef MNNCORRECT_HPP
2#define MNNCORRECT_HPP
3
4#include <algorithm>
5#include <vector>
6#include <numeric>
7#include <stdexcept>
8#include <cstddef>
9
10#include "knncolle/knncolle.hpp"
11#include "sanisizer/sanisizer.hpp"
12
13#include "Coordinator.hpp"
14#include "reorder_matrix_in_place.hpp"
15#include "utils.hpp"
16
26namespace mnncorrect {
27
36template<typename Index_, typename Float_, class Matrix_ = knncolle::Matrix<Index_, Float_> >
37struct Options {
45 int num_neighbors = 15;
46
51 int num_steps = 1;
52
57 std::shared_ptr<knncolle::Builder<Index_, Float_, Float_, Matrix_> > builder;
58
62 MergePolicy merge_policy = MergePolicy::RSS;
63
68 int num_threads = 1;
69};
70
74template<typename Index_, typename Float_, class Matrix_>
75void compute_internal(
76 const std::size_t num_dim,
77 const Index_ num_total,
78 const std::vector<Batch<Index_> >& batches,
79 Float_* const data,
81) {
82 auto builder = options.builder;
83 if (!builder) {
85 builder.reset(new knncolle::VptreeBuilder<Index_, Float_, Float_, Matrix_, Euclidean>(std::make_shared<Euclidean>()));
86 }
87
88 Coordinator<Index_, Float_, Matrix_> runner(
89 num_dim,
90 num_total,
91 batches,
92 data,
93 *builder,
94 options.num_neighbors,
95 options.num_steps,
96 options.merge_policy,
97 options.num_threads
98 );
99
100 runner.merge();
101}
148template<typename Index_, typename Float_, class Matrix_>
149void compute(const std::size_t num_dim, const std::vector<Batch<Index_> >& batches, Float_* const data, const Options<Index_, Float_, Matrix_>& options) {
150 Index_ num_total = 0;
151 for (const auto& batch : batches) {
152 num_total = sanisizer::sum<Index_>(num_total, batch.size);
153 }
154 compute_internal(num_dim, num_total, batches, data, options);
155}
156
178template<typename Index_, typename Float_, typename Batch_, class Matrix_>
180 const std::size_t num_dim,
181 const Index_ num_obs,
182 Float_* const data,
183 const Batch_* const batch,
184 const BatchIndex num_batches,
186) {
187 // Avoiding allocation of a temporary buffer if we're already dealing with contiguous batches.
188 auto batches = sanisizer::create<std::vector<Batch<Index_> > >(num_batches);
189 Index_ non_contiguous = 0;
190 for (Index_ o = 0; o < num_obs; ++o) {
191 auto& curbatch = batches[batch[o]];
192 if (curbatch.size == 0) {
193 curbatch.start = o;
194 curbatch.size = 1;
195 } else {
196 non_contiguous += (o != curbatch.start + curbatch.size);
197 ++curbatch.size;
198 }
199 }
200
201 if (non_contiguous == 0) {
202 compute_internal(num_dim, num_obs, batches, data, options);
203 return;
204 }
205
206 // Otherwise, we reorganize the data so that observations from the same batch are in a single block.
207 Index_ accumulated = 0;
208 auto offsets = sanisizer::create<std::vector<Index_> >(num_batches);
209 for (BatchIndex b = 0; b < num_batches; ++b) {
210 offsets[b] = accumulated;
211 batches[b].start = accumulated;
212 accumulated += batches[b].size; // this won't overflow as know that num_obs fits in an Index_.
213 }
214
215 auto reordered = sanisizer::create<std::vector<Index_> >(num_obs);
216 for (Index_ o = 0; o < num_obs; ++o) {
217 auto& offset = offsets[batch[o]];
218 reordered[offset] = o;
219 ++offset;
220 }
221 auto mbuffer = sanisizer::create<std::vector<Float_> >(num_dim);
222 reorder_matrix_in_place(num_dim, num_obs, reordered, data, mbuffer);
223
224 compute_internal(num_dim, num_obs, batches, data, options);
225
226 // Reorganizing back to the original ordering.
227 for (BatchIndex b = 0; b < num_batches; ++b) {
228 offsets[b] = batches[b].start;
229 }
230 for (Index_ o = 0; o < num_obs; ++o) {
231 auto& offset = offsets[batch[o]];
232 reordered[o] = offset;
233 ++offset;
234 }
235 reorder_matrix_in_place(num_dim, num_obs, reordered, data, mbuffer);
236}
237
238}
239
240#endif
Batch correction with mutual nearest neighbors.
Definition utils.hpp:21
MergePolicy
Definition utils.hpp:43
std::size_t BatchIndex
Definition utils.hpp:26
void compute(const std::size_t num_dim, const std::vector< Batch< Index_ > > &batches, Float_ *const data, const Options< Index_, Float_, Matrix_ > &options)
Definition mnncorrect.hpp:149
Start and size of each batch.
Definition utils.hpp:72
Options for compute().
Definition mnncorrect.hpp:37
int num_steps
Definition mnncorrect.hpp:51
std::shared_ptr< knncolle::Builder< Index_, Float_, Float_, Matrix_ > > builder
Definition mnncorrect.hpp:57
int num_threads
Definition mnncorrect.hpp:68
int num_neighbors
Definition mnncorrect.hpp:45
MergePolicy merge_policy
Definition mnncorrect.hpp:62
Utilities for MNN correction.