175 std::vector<const Float_*> batches;
176 batches.reserve(num_obs.size());
178 Index_ accumulated = 0;
179 for (
const auto n : num_obs) {
180 batches.push_back(input + sanisizer::product_unsafe<std::size_t>(accumulated, num_dim));
183 accumulated = sanisizer::sum<decltype(I(accumulated))>(accumulated, n);
186 compute(num_dim, num_obs, batches, output, options);
212 const BatchIndex nbatches = (num_obs ? sanisizer::sum<BatchIndex>(*std::max_element(batch, batch + num_obs), 1) :
static_cast<BatchIndex>(0));
213 auto sizes = sanisizer::create<std::vector<Index_> >(nbatches);
214 for (Index_ o = 0; o < num_obs; ++o) {
220 bool already_sorted =
true;
221 for (Index_ o = 1; o < num_obs; ++o) {
222 if (batch[o] < batch[o-1]) {
223 already_sorted =
false;
227 if (already_sorted) {
228 compute(num_dim, sizes, input, output, options);
232 Index_ accumulated = 0;
233 auto offsets = sanisizer::create<std::vector<Index_> >(nbatches);
234 std::vector<Float_> tmp(sanisizer::product<
typename std::vector<Float_>::size_type>(num_dim, num_obs));
235 auto ptrs = sanisizer::create<std::vector<const Float_*> >(nbatches);
237 ptrs[b] = tmp.data() + sanisizer::product_unsafe<std::size_t>(accumulated, num_dim);
238 offsets[b] = accumulated;
239 accumulated += sizes[b];
242 for (Index_ o = 0; o < num_obs; ++o) {
243 auto& offset = offsets[batch[o]];
245 input + sanisizer::product_unsafe<std::size_t>(o, num_dim),
247 tmp.data() + sanisizer::product_unsafe<std::size_t>(offset, num_dim)
252 internal::compute(num_dim, sizes, ptrs, output, options);
253 internal::restore_input_order(num_dim, sizes, batch, output);
void compute(const std::size_t num_dim, const std::vector< Index_ > &num_obs, const std::vector< const Float_ * > &batches, Float_ *const output, const Options< Index_, Float_, Matrix_ > &options)
Definition mnncorrect.hpp:148
std::shared_ptr< knncolle::Builder< Index_, Float_, Float_, Matrix_ > > builder
Definition mnncorrect.hpp:57