103template<
typename Stat_>
 
  177template<
typename Stat_>
 
  185    std::vector<std::vector<Stat_> > 
mean;
 
 
  237template<
typename Index_, 
typename Stat_>
 
  238void process_simple_pairwise_effects(
 
  240    const std::size_t ngroups,
 
  241    const std::size_t nblocks,
 
  242    const std::size_t ncombos,
 
  243    std::vector<Stat_>& combo_means,
 
  244    std::vector<Stat_>& combo_vars,
 
  245    std::vector<Stat_>& combo_detected,
 
  247    const std::vector<Stat_>& combo_weights,
 
  248    const double threshold,
 
  249    const int num_threads)
 
  251    std::vector<Stat_> total_weights_per_group;
 
  252    const Stat_* total_weights_ptr = combo_weights.data();
 
  254        total_weights_per_group = compute_total_weight_per_group(ngroups, nblocks, combo_weights.data());
 
  255        total_weights_ptr = total_weights_per_group.data();
 
  257    PrecomputedPairwiseWeights<Stat_> preweights(ngroups, nblocks, combo_weights.data());
 
  260        for (Index_ gene = start, end = start + length; gene < end; ++gene) {
 
  261            auto in_offset = sanisizer::product_unsafe<std::size_t>(gene, ncombos);
 
  263            if (!output.
mean.empty()) {
 
  264                const auto tmp_means = combo_means.data() + in_offset;
 
  265                average_group_stats(gene, ngroups, nblocks, tmp_means, combo_weights.data(), total_weights_ptr, output.
mean);
 
  268                const auto tmp_detected = combo_detected.data() + in_offset;
 
  269                average_group_stats(gene, ngroups, nblocks, tmp_detected, combo_weights.data(), total_weights_ptr, output.
detected);
 
  273            const auto out_offset = sanisizer::product_unsafe<std::size_t>(gene, ngroups, ngroups);
 
  276                const auto tmp_means = combo_means.data() + in_offset;
 
  277                const auto tmp_variances = combo_vars.data() + in_offset;
 
  278                compute_pairwise_cohens_d(tmp_means, tmp_variances, ngroups, nblocks, preweights, threshold, output.
cohens_d + out_offset);
 
  282                const auto tmp_detected = combo_detected.data() + in_offset;
 
  283                compute_pairwise_simple_diff(tmp_detected, ngroups, nblocks, preweights, output.
delta_detected + out_offset);
 
  287                const auto tmp_means = combo_means.data() + in_offset;
 
  288                compute_pairwise_simple_diff(tmp_means, ngroups, nblocks, preweights, output.
delta_mean + out_offset);
 
  291    }, ngenes, num_threads);
 
  294template<
typename Index_, 
typename Stat_>
 
  295ScoreMarkersPairwiseBuffers<Stat_> preallocate_pairwise_results(
const Index_ ngenes, 
const std::size_t ngroups, ScoreMarkersPairwiseResults<Stat_>& store, 
const ScoreMarkersPairwiseOptions& opt) {
 
  296    ScoreMarkersPairwiseBuffers<Stat_> output;
 
  298    if (opt.compute_group_mean) {
 
  299        preallocate_average_results(ngenes, ngroups, store.mean, output.mean);
 
  301    if (opt.compute_group_detected) {
 
  302        preallocate_average_results(ngenes, ngroups, store.detected, output.detected);
 
  305    const auto num_effect_sizes = sanisizer::product<typename std::vector<Stat_>::size_type>(ngenes, ngroups, ngroups);
 
  307    if (opt.compute_cohens_d) {
 
  308        store.cohens_d.resize(num_effect_sizes
 
  309#ifdef SCRAN_MARKERS_TEST_INIT
 
  310            , SCRAN_MARKERS_TEST_INIT
 
  313        output.cohens_d = store.cohens_d.data();
 
  315    if (opt.compute_auc) {
 
  316        store.auc.resize(num_effect_sizes
 
  317#ifdef SCRAN_MARKERS_TEST_INIT
 
  318            , SCRAN_MARKERS_TEST_INIT
 
  321        output.auc = store.auc.data();
 
  323    if (opt.compute_delta_mean) {
 
  324        store.delta_mean.resize(num_effect_sizes
 
  325#ifdef SCRAN_MARKERS_TEST_INIT
 
  326            , SCRAN_MARKERS_TEST_INIT
 
  329        output.delta_mean = store.delta_mean.data();
 
  331    if (opt.compute_delta_detected) {
 
  332        store.delta_detected.resize(num_effect_sizes
 
  333#ifdef SCRAN_MARKERS_TEST_INIT
 
  334            , SCRAN_MARKERS_TEST_INIT
 
  337        output.delta_detected = store.delta_detected.data();
 
  353    const std::size_t ngroups,
 
  354    const Group_* 
const group, 
 
  355    const std::size_t nblocks,
 
  356    const Block_* 
const block,
 
  357    const std::size_t ncombos,
 
  358    const std::size_t* 
const combo,
 
  359    const std::vector<Index_>& combo_sizes,
 
  360    const ScoreMarkersPairwiseOptions& options,
 
  361    const ScoreMarkersPairwiseBuffers<Stat_>& output
 
  363    const auto ngenes = matrix.
nrow();
 
  364    const auto payload_size = sanisizer::product<typename std::vector<Stat_>::size_type>(ngenes, ncombos);
 
  365    std::vector<Stat_> combo_means, combo_vars, combo_detected;
 
  366    if (!output.mean.empty() || output.cohens_d != NULL || output.delta_mean != NULL) {
 
  367        combo_means.resize(payload_size);
 
  369    if (output.cohens_d != NULL) {
 
  370        combo_vars.resize(payload_size);
 
  372    if (!output.detected.empty() || output.delta_detected != NULL) {
 
  373        combo_detected.resize(payload_size);
 
  380        options.block_weight_policy,
 
  381        options.variable_block_weight_parameters
 
  385        scan_matrix_by_row_full_auc<single_block_>(
 
  404        scan_matrix_by_column(
 
  407                if constexpr(single_block_) {
 
  414                if constexpr(single_block_) {
 
  428    process_simple_pairwise_effects(
 
  518template<
typename Value_, 
typename Index_, 
typename Group_, 
typename Stat_>
 
  521    const Group_* 
const group, 
 
  525    const Index_ NC = matrix.
ncol();
 
  526    const auto group_sizes = tatami_stats::tabulate_groups(group, NC); 
 
  527    const auto ngroups = sanisizer::cast<std::size_t>(group_sizes.size());
 
  529    internal::score_markers_pairwise<true>(
 
  534        static_cast<int*
>(NULL),
 
  536        static_cast<std::size_t*
>(NULL),
 
 
  582template<
typename Value_, 
typename Index_, 
typename Group_, 
typename Block_, 
typename Stat_>
 
  585    const Group_* 
const group, 
 
  586    const Block_* 
const block,
 
  590    const Index_ NC = matrix.
ncol();
 
  591    const auto ngroups = output.
mean.size();
 
  592    const auto nblocks = tatami_stats::total_groups(block, NC); 
 
  594    const auto combinations = internal::create_combinations(ngroups, group, block, NC);
 
  595    const auto combo_sizes = internal::tabulate_combinations<Index_>(ngroups, nblocks, combinations);
 
  596    const auto ncombos = combo_sizes.size();
 
  598    internal::score_markers_pairwise<false>(
 
  600        sanisizer::cast<std::size_t>(ngroups),
 
  602        sanisizer::cast<std::size_t>(nblocks),
 
  604        sanisizer::cast<std::size_t>(ncombos),
 
 
  628template<
typename Stat_ = 
double, 
typename Value_, 
typename Index_, 
typename Group_>
 
  630    const auto ngroups = tatami_stats::total_groups(group, matrix.
ncol());
 
  632    auto buffers = internal::preallocate_pairwise_results(matrix.
nrow(), ngroups, res, options);
 
 
  656template<
typename Stat_ = 
double, 
typename Value_, 
typename Index_, 
typename Group_, 
typename Block_>
 
  659    const Group_* 
const group,
 
  660    const Block_* 
const block,
 
  663    const auto ngroups = tatami_stats::total_groups(group, matrix.
ncol());
 
  665    const auto buffers = internal::preallocate_pairwise_results(matrix.
nrow(), ngroups, res, options);