1#ifndef MUMOSA_BLOCKED_HPP
2#define MUMOSA_BLOCKED_HPP
9#include "sanisizer/sanisizer.hpp"
11#include "quickstats/quickstats.hpp"
59template<
typename Distance_>
64 std::vector<Distance_> weights;
65 Distance_ total_weight;
67 std::vector<Distance_> distance_buffer;
82template<
typename Distance_,
typename Index_>
87 quickstats::PairwiseSumWorkspace<Distance_> pswrk;
88 quickstats::PairwiseSumOptions psopt;
89 output.total_weight = quickstats::pairwise_sum(output.weights.size(), output.weights.data(), pswrk, psopt);
92 if (block_sizes.size()) {
93 max_size = *std::max_element(block_sizes.begin(), block_sizes.end());
95 sanisizer::resize(output.distance_buffer, max_size);
137template<
typename Index_,
typename Input_,
typename Distance_>
147 std::pair<Distance_, Distance_> output(0, 0);
149 const auto nblocks = prebuilts.size();
150 for (I<
decltype(nblocks)> b = 0; b < nblocks; ++b) {
151 const auto curweight = workspace.weights[b];
152 const auto& pbptr = prebuilts[b];
153 if (curweight && pbptr && pbptr->num_observations()) {
154 const auto curdist =
compute_distance(*pbptr, workspace.distance_buffer.data(), simple_opt);
155 output.first += curdist.first * curweight;
156 output.second += curdist.second * curweight;
160 if (workspace.total_weight) {
161 output.first /= workspace.total_weight;
162 output.second /= workspace.total_weight;
190template<
typename Index_,
typename Input_,
typename Distance_,
class Matrix_ = knncolle::Matrix<Index_, Input_> >
192 const std::size_t num_dim,
193 const std::vector<Index_> block_sizes,
194 const Input_*
const data,
197 const auto num_blocks = block_sizes.size();
198 auto prebuilts = sanisizer::create<std::vector<std::shared_ptr<const knncolle::Prebuilt<Index_, Input_, Distance_> > > >(num_blocks);
201 for (I<
decltype(num_blocks)> b = 0; b < num_blocks; ++b) {
202 const auto cursize = block_sizes[b];
233template<
typename Index_,
typename Input_,
typename Distance_,
class Matrix_ = knncolle::Matrix<Index_, Input_> >
235 const std::size_t num_dim,
236 const std::vector<Index_>& block_sizes,
237 const Input_*
const data,
255template<
typename Index_,
typename Block_>
259 const Block_* my_blocks;
260 Block_ my_num_blocks = 0;
261 std::vector<Index_> my_block_sizes;
263 std::vector<std::pair<Index_, Index_> > my_contigs;
264 Index_ my_non_contig_total = 0;
265 std::vector<Index_> my_non_contig_offsets;
276 const Index_ num_cells,
277 const Block_* blocks,
278 const std::size_t num_blocks
280 my_num_cells(num_cells),
282 my_num_blocks(num_blocks)
284 sanisizer::resize(my_block_sizes, my_num_blocks);
285 auto block_non_contig = sanisizer::create<std::vector<char> >(my_num_blocks);
286 auto& block_ends = my_non_contig_offsets;
287 sanisizer::resize(block_ends, my_num_blocks);
289 for (Index_ c = 0; c < my_num_cells; ++c) {
290 const auto curb = my_blocks[c];
291 my_block_sizes[curb] += 1;
293 auto& nc = block_non_contig[curb];
295 auto& be = block_ends[curb];
298 }
else if (be == c) {
306 sanisizer::resize(my_contigs, my_num_blocks);
308 for (Block_ b = 0; b < my_num_blocks; ++b) {
309 const auto length = my_block_sizes[b];
310 if (block_non_contig[b]) {
311 my_non_contig_offsets[b] = my_non_contig_total;
312 my_non_contig_total += length;
314 const auto start = block_ends[b] - length;
315 my_contigs[b] = std::make_pair(start, length);
325 const std::vector<Index_>&
sizes()
const {
326 return my_block_sizes;
333 template<
typename Input_>
338 std::vector<Index_> tmp_offsets;
339 std::vector<Input_> tmp_buffer;
348 template<
typename Input_>
370 template<
typename Input_,
typename Distance_,
class Matrix_ = knncolle::Matrix<Index_, Input_> >
372 const std::size_t num_dim,
373 const Input_*
const data,
379 sanisizer::resize(output, my_num_blocks);
381 for (Block_ b = 0; b < my_num_blocks; ++b) {
382 const auto& con = my_contigs[b];
384 const auto ptr = data + sanisizer::product_unsafe<std::size_t>(con.first, num_dim);
389 if (my_non_contig_total) {
390 work.tmp_buffer.resize(sanisizer::product<I<
decltype(work.tmp_buffer.size())> >(my_non_contig_total, num_dim));
391 work.tmp_offsets.clear();
392 work.tmp_offsets.insert(work.tmp_offsets.end(), my_non_contig_offsets.begin(), my_non_contig_offsets.end());
395 while (c < my_num_cells) {
396 const auto curb = my_blocks[c];
397 const auto& con = my_contigs[curb];
401 auto& curoff = work.tmp_offsets[curb];
403 data + sanisizer::product_unsafe<std::size_t>(c, num_dim),
405 work.tmp_buffer.data() + sanisizer::product_unsafe<std::size_t>(curoff, num_dim)
412 for (Block_ b = 0; b < my_num_blocks; ++b) {
413 if (my_contigs[b].second == 0) {
414 const auto length = my_block_sizes[b];
415 const auto ptr = work.tmp_buffer.data() + sanisizer::product_unsafe<std::size_t>(my_non_contig_offsets[b], num_dim);
439 template<
typename Input_,
typename Distance_,
class Matrix_ = knncolle::Matrix<Index_, Input_> >
440 std::vector<std::shared_ptr<const knncolle::Prebuilt<Index_, Input_, Distance_> > >
build(
441 const std::size_t num_dim,
442 const Input_*
const data,
445 std::vector<std::shared_ptr<const knncolle::Prebuilt<Index_, Input_, Distance_> > > prebuilts;
447 build(num_dim, data, builder, prebuilts, bufs);
476template<
typename Index_,
typename Input_,
typename Block_,
typename Distance_,
class Matrix_ = knncolle::Matrix<Index_, Input_> >
478 const std::size_t num_dim,
479 const Index_ num_cells,
480 const Input_*
const data,
481 const Block_*
const blocks,
482 const std::size_t num_blocks,
487 const auto prebuilts = blocked_factory.
build(num_dim, data, builder);
std::shared_ptr< Prebuilt< Index_, Data_, Distance_ > > build_shared(const Matrix_ &data) const
Factory for creating nearest-neighbor search indices for each block.
Definition blocked.hpp:256
void build(const std::size_t num_dim, const Input_ *const data, const knncolle::Builder< Index_, Input_, Distance_, Matrix_ > &builder, std::vector< std::shared_ptr< const knncolle::Prebuilt< Index_, Input_, Distance_ > > > &output, Buffers< Input_ > &work) const
Definition blocked.hpp:371
BlockedIndicesFactory(const Index_ num_cells, const Block_ *blocks, const std::size_t num_blocks)
Definition blocked.hpp:275
const std::vector< Index_ > & sizes() const
Definition blocked.hpp:325
Buffers< Input_ > create_buffers() const
Definition blocked.hpp:349
std::vector< std::shared_ptr< const knncolle::Prebuilt< Index_, Input_, Distance_ > > > build(const std::size_t num_dim, const Input_ *const data, const knncolle::Builder< Index_, Input_, Distance_, Matrix_ > &builder) const
Definition blocked.hpp:440
Scale multi-modal embeddings to adjust for differences in variance.
Definition blocked.hpp:21
std::pair< Distance_, Distance_ > compute_distance_blocked(const std::vector< std::shared_ptr< const knncolle::Prebuilt< Index_, Input_, Distance_ > > > &prebuilts, BlockedWorkspace< Distance_ > &workspace, const BlockedOptions &options)
Definition blocked.hpp:138
std::pair< Distance_, Distance_ > compute_distance(const Index_ num_cells, Distance_ *const distances)
Definition simple.hpp:59
std::vector< std::shared_ptr< const knncolle::Prebuilt< Index_, Input_, Distance_ > > > build_blocked_indices(const std::size_t num_dim, const std::vector< Index_ > block_sizes, const Input_ *const data, const knncolle::Builder< Index_, Input_, Distance_, Matrix_ > &builder)
Definition blocked.hpp:191
BlockedWorkspace< Distance_ > create_workspace(const std::vector< Index_ > &block_sizes, const BlockedOptions &options)
Definition blocked.hpp:83
void compute_weights(const std::size_t num_blocks, const Size_ *const sizes, const WeightPolicy policy, const VariableWeightParameters &variable, Weight_ *const weights)
Compute distances to nearest neighbors.
Temporary buffers for build().
Definition blocked.hpp:334
Options for compute_distance_blocked().
Definition blocked.hpp:26
scran_blocks::VariableWeightParameters variable_block_weight_parameters
Definition blocked.hpp:43
scran_blocks::WeightPolicy block_weight_policy
Definition blocked.hpp:37
int num_threads
Definition blocked.hpp:49
int num_neighbors
Definition blocked.hpp:32
Workspace for compute_distance_blocked().
Definition blocked.hpp:60
Options for compute_distance().
Definition simple.hpp:28
int num_threads
Definition simple.hpp:40
int num_neighbors
Definition simple.hpp:34