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);