@@ -299,6 +299,97 @@ ScoreMarkersPairwiseBuffers<Stat_> fill_pairwise_results(const Index_ ngenes, co
299299 return output;
300300}
301301
302+ template <
303+ bool single_block_,
304+ typename Value_,
305+ typename Index_,
306+ typename Group_,
307+ typename Block_,
308+ typename Stat_
309+ >
310+ void score_markers_pairwise (
311+ const tatami::Matrix<Value_, Index_>& matrix,
312+ const std::size_t ngroups,
313+ const Group_* const group,
314+ const std::size_t nblocks,
315+ const Block_* const block,
316+ const std::size_t ncombos,
317+ const std::size_t * const combo,
318+ const std::vector<Index_>& combo_sizes,
319+ const ScoreMarkersPairwiseOptions& options,
320+ const ScoreMarkersPairwiseBuffers<Stat_>& output
321+ ) {
322+ const auto ngenes = matrix.nrow ();
323+ const auto payload_size = sanisizer::product<typename std::vector<Stat_>::size_type>(ngenes, ncombos);
324+ std::vector<Stat_> combo_means (payload_size), combo_vars (payload_size), combo_detected (payload_size);
325+
326+ // For a single block, this usually doesn't really matter, but we do it for consistency with the multi-block case,
327+ // and to account for variable weighting where non-zero block sizes get zero weight.
328+ const auto combo_weights = scran_blocks::compute_weights<Stat_>(
329+ combo_sizes,
330+ options.block_weight_policy ,
331+ options.variable_block_weight_parameters
332+ );
333+
334+ if (output.auc != NULL || matrix.prefer_rows ()) {
335+ scan_matrix_by_row_full_auc<single_block_>(
336+ matrix,
337+ ngroups,
338+ group,
339+ nblocks,
340+ block,
341+ ncombos,
342+ combo,
343+ combo_means,
344+ combo_vars,
345+ combo_detected,
346+ output.auc ,
347+ combo_sizes,
348+ combo_weights,
349+ options.threshold ,
350+ options.num_threads
351+ );
352+
353+ } else {
354+ scan_matrix_by_column (
355+ matrix,
356+ [&]{
357+ if constexpr (single_block_) {
358+ return ngroups;
359+ } else {
360+ return ncombos;
361+ }
362+ }(),
363+ [&]{
364+ if constexpr (single_block_) {
365+ return group;
366+ } else {
367+ return combo;
368+ }
369+ }(),
370+ combo_means,
371+ combo_vars,
372+ combo_detected,
373+ combo_sizes,
374+ options.num_threads
375+ );
376+ }
377+
378+ process_simple_pairwise_effects (
379+ matrix.nrow (),
380+ ngroups,
381+ nblocks,
382+ ncombos,
383+ combo_means,
384+ combo_vars,
385+ combo_detected,
386+ output,
387+ combo_weights,
388+ options.threshold ,
389+ options.num_threads
390+ );
391+ }
392+
302393}
303394/* *
304395 * @endcond
@@ -379,63 +470,23 @@ void score_markers_pairwise(
379470 const tatami::Matrix<Value_, Index_>& matrix,
380471 const Group_* const group,
381472 const ScoreMarkersPairwiseOptions& options,
382- const ScoreMarkersPairwiseBuffers<Stat_>& output)
383- {
473+ const ScoreMarkersPairwiseBuffers<Stat_>& output
474+ ) {
384475 const Index_ NC = matrix.ncol ();
385476 const auto group_sizes = tatami_stats::tabulate_groups (group, NC);
477+ const auto ngroups = sanisizer::cast<std::size_t >(group_sizes.size ());
386478
387- // In most cases this doesn't really matter, but we do it for consistency with the 1-block case,
388- // and to account for variable weighting where non-zero block sizes get zero weight.
389- const auto group_weights = scran_blocks::compute_weights<Stat_>(group_sizes, options.block_weight_policy , options.variable_block_weight_parameters );
390-
391- const auto ngroups = group_sizes.size ();
392- const auto payload_size = sanisizer::product<typename std::vector<Stat_>::size_type>(matrix.nrow (), ngroups);
393- std::vector<Stat_> group_means (payload_size), group_vars (payload_size), group_detected (payload_size);
394-
395- if (output.auc != NULL || matrix.prefer_rows ()) {
396- internal::scan_matrix_by_row_full_auc<true >(
397- matrix,
398- ngroups,
399- group,
400- 1 ,
401- static_cast <int *>(NULL ),
402- ngroups,
403- static_cast <std::size_t *>(NULL ),
404- group_means,
405- group_vars,
406- group_detected,
407- output.auc ,
408- group_sizes,
409- group_weights,
410- options.threshold ,
411- options.num_threads
412- );
413-
414- } else {
415- internal::scan_matrix_by_column (
416- matrix,
417- ngroups,
418- group,
419- group_means,
420- group_vars,
421- group_detected,
422- group_sizes,
423- options.num_threads
424- );
425- }
426-
427- internal::process_simple_pairwise_effects (
428- matrix.nrow (),
479+ internal::score_markers_pairwise<true >(
480+ matrix,
429481 ngroups,
482+ group,
430483 1 ,
484+ static_cast <int *>(NULL ),
431485 ngroups,
432- group_means,
433- group_vars,
434- group_detected,
435- output,
436- group_weights,
437- options.threshold ,
438- options.num_threads
486+ static_cast <std::size_t *>(NULL ),
487+ group_sizes,
488+ options,
489+ output
439490 );
440491}
441492
@@ -484,64 +535,27 @@ void score_markers_pairwise_blocked(
484535 const Group_* const group,
485536 const Block_* const block,
486537 const ScoreMarkersPairwiseOptions& options,
487- const ScoreMarkersPairwiseBuffers<Stat_>& output)
488- {
538+ const ScoreMarkersPairwiseBuffers<Stat_>& output
539+ ) {
489540 const Index_ NC = matrix.ncol ();
490541 const auto ngroups = output.mean .size ();
491542 const auto nblocks = tatami_stats::total_groups (block, NC);
492543
493544 const auto combinations = internal::create_combinations (ngroups, group, block, NC);
494545 const auto combo_sizes = internal::tabulate_combinations<Index_>(ngroups, nblocks, combinations);
495546 const auto ncombos = combo_sizes.size ();
496- const auto combo_weights = scran_blocks::compute_weights<Stat_>(combo_sizes, options.block_weight_policy , options.variable_block_weight_parameters );
497-
498- const auto payload_size = sanisizer::product<typename std::vector<Stat_>::size_type>(matrix.nrow (), ncombos);
499- std::vector<Stat_> combo_means (payload_size), combo_vars (payload_size), combo_detected (payload_size);
500547
501- if (output.auc != NULL || matrix.prefer_rows ()) {
502- internal::scan_matrix_by_row_full_auc<false >(
503- matrix,
504- ngroups,
505- group,
506- nblocks,
507- block,
508- ncombos,
509- combinations.data (),
510- combo_means,
511- combo_vars,
512- combo_detected,
513- output.auc ,
514- combo_sizes,
515- combo_weights,
516- options.threshold ,
517- options.num_threads
518- );
519-
520- } else {
521- internal::scan_matrix_by_column (
522- matrix,
523- ncombos,
524- combinations.data (),
525- combo_means,
526- combo_vars,
527- combo_detected,
528- combo_sizes,
529- options.num_threads
530- );
531- }
532-
533- internal::process_simple_pairwise_effects (
534- matrix.nrow (),
535- ngroups,
536- nblocks,
537- ncombos,
538- combo_means,
539- combo_vars,
540- combo_detected,
541- output,
542- combo_weights,
543- options.threshold ,
544- options.num_threads
548+ internal::score_markers_pairwise<false >(
549+ matrix,
550+ sanisizer::cast<std::size_t >(ngroups),
551+ group,
552+ sanisizer::cast<std::size_t >(nblocks),
553+ block,
554+ sanisizer::cast<std::size_t >(ncombos),
555+ combinations.data (),
556+ combo_sizes,
557+ options,
558+ output
545559 );
546560}
547561
0 commit comments