1#ifndef MEDIAN_MARKERS_BLOCKED_HPP
2#define MEDIAN_MARKERS_BLOCKED_HPP
10#include "sanisizer/sanisizer.hpp"
12#include "tatami_stats/tatami_stats.hpp"
54template<
bool include_stat_,
typename Stat_,
typename Value_,
typename Index_,
typename Label_,
typename Block_>
55Markers<include_stat_, Index_, Stat_> choose_blocked_raw(
61 const auto NC = matrix.
ncol();
62 const std::size_t ngroups = tatami_stats::total_groups(label, NC);
63 const std::size_t nblocks = tatami_stats::total_groups(block, NC);
65 const auto num_keep = get_num_keep<Index_>(ngroups, options.
number);
66 auto pqueues = sanisizer::create<std::vector<std::optional<PairwiseTopQueues<Stat_, Index_> > > >(options.
num_threads);
69 const auto ncombos = sanisizer::product<std::size_t>(ngroups, nblocks);
70 auto combinations = sanisizer::create<std::vector<std::size_t> >(NC);
71 for (I<
decltype(NC)> c = 0; c < NC; ++c) {
72 combinations[c] = sanisizer::nd_offset<std::size_t>(label[c], ngroups, block[c]);
74 auto combo_sizes = tatami_stats::tabulate_groups(combinations.data(), NC);
76 const auto num_used = scan_matrix<Stat_>(
78 sanisizer::cast<std::size_t>(ncombos),
82 [&]() -> PairwiseTopQueues<Stat_, Index_> {
83 PairwiseTopQueues<Stat_, Index_> output;
84 allocate_pairwise_queues(output, num_keep, ngroups, options.keep_ties, false);
88 [&](
const Index_ r,
const std::vector<Stat_>& medians, PairwiseTopQueues<Stat_, Index_>& curqueues) ->
void {
89 for (I<decltype(ngroups)> g1 = 1; g1 < ngroups; ++g1) {
90 for (I<decltype(ngroups)> g2 = 0; g2 < g1; ++g2) {
92 if (options.use_minimum) {
93 Stat_ xval = std::numeric_limits<Stat_>::infinity();
94 Stat_ yval = std::numeric_limits<Stat_>::infinity();
95 for (I<decltype(nblocks)> b = 0; b < nblocks; ++b) {
96 const auto delta = medians[sanisizer::nd_offset<std::size_t>(g1, ngroups, b)] - medians[sanisizer::nd_offset<std::size_t>(g2, ngroups, b)];
97 if (!std::isnan(delta)) {
98 xval = std::min(xval, delta);
99 yval = std::min(yval, -delta);
103 if (std::isfinite(xval)) {
104 curqueues[g1][g2].emplace(xval, r);
105 curqueues[g2][g1].emplace(yval, r);
110 std::size_t denom = 0;
111 for (I<decltype(nblocks)> b = 0; b < nblocks; ++b) {
112 const auto delta = medians[sanisizer::nd_offset<std::size_t>(g1, ngroups, b)] - medians[sanisizer::nd_offset<std::size_t>(g2, ngroups, b)];
113 if (!std::isnan(delta)) {
121 curqueues[g1][g2].emplace(val, r);
122 curqueues[g2][g1].emplace(-val, r);
130 [&](
const int t, PairwiseTopQueues<Stat_, Index_>& curqueues) ->
void {
131 pqueues[t] = std::move(curqueues);
137 pqueues.resize(num_used);
138 Markers<include_stat_, Index_, Stat_> output;
139 report_best_top_queues<include_stat_>(pqueues, ngroups, output);
171template<
typename Stat_ =
double,
typename Value_,
typename Index_,
typename Label_,
typename Block_>
172std::vector<std::vector<std::vector<std::pair<Index_, Stat_> > > >
choose_blocked(
178 return choose_blocked_raw<true, Stat_>(matrix, label, block, options);
203template<
typename Stat_ =
double,
typename Value_,
typename Index_,
typename Label_,
typename Block_>
210 return choose_blocked_raw<false, Stat_>(matrix, label, block, options);
virtual Index_ ncol() const=0
Implementation of the classic SingleR marker detection.
Definition choose.hpp:21
std::vector< std::vector< std::vector< std::pair< Index_, Stat_ > > > > choose_blocked(const tatami::Matrix< Value_, Index_ > &matrix, const Label_ *label, const Block_ *block, const ChooseBlockedOptions &options)
Definition blocked.hpp:172
std::vector< std::vector< std::vector< Index_ > > > choose_blocked_index(const tatami::Matrix< Value_, Index_ > &matrix, const Label_ *label, const Block_ *block, const ChooseBlockedOptions &options)
Definition blocked.hpp:204
Options for choose_blocked().
Definition blocked.hpp:23
int num_threads
Definition blocked.hpp:48
std::optional< std::size_t > number
Definition blocked.hpp:28
bool use_minimum
Definition blocked.hpp:42
bool keep_ties
Definition blocked.hpp:35