1#ifndef TOPICKER_TOPICKER_HPP
2#define TOPICKER_TOPICKER_HPP
9#include "sanisizer/sanisizer.hpp"
22template<
typename Stat_>
43template<
bool keep_index_,
typename Index_,
typename Stat_,
typename Top_,
class Output_,
class Cmp_,
class CmpEqual_>
46 if constexpr(keep_index_) {
49 std::fill_n(output, n,
false);
54 if (sanisizer::is_greater_than(top, n)) {
55 if (options.
bound.has_value()) {
56 auto bound = *(options.
bound);
57 for (Index_ i = 0; i < n; ++i) {
58 bool ok = cmp(statistic[i], bound);
59 if constexpr(keep_index_) {
68 if constexpr(keep_index_) {
69 output.resize(sanisizer::cast<
decltype(output.size())>(n));
70 std::iota(output.begin(), output.end(),
static_cast<Index_
>(0));
72 std::fill_n(output, n,
true);
78 auto semi_sorted = sanisizer::create<std::vector<Index_> >(n);
79 std::iota(semi_sorted.begin(), semi_sorted.end(),
static_cast<Index_
>(0));
80 auto cBegin = semi_sorted.begin(), cMid = cBegin + top - 1, cEnd = semi_sorted.end();
81 std::nth_element(cBegin, cMid, cEnd, [&](Index_ l, Index_ r) ->
bool {
82 auto L = statistic[l], R = statistic[r];
89 Stat_ threshold = statistic[*cMid];
92 if (options.
bound.has_value() && !cmp(threshold, *(options.
bound))) {
93 auto bound = *(options.
bound);
94 for (Index_ i = 0; i < n; ++i) {
95 bool ok = cmp(statistic[i], bound);
96 if constexpr(keep_index_) {
105 for (Index_ i = 0; i < n; ++i) {
106 bool ok = cmpeq(statistic[i], threshold);
107 if constexpr(keep_index_) {
119 if constexpr(keep_index_) {
120 output.reserve(sanisizer::cast<
decltype(output.size())>(top));
122 std::fill_n(output, n,
false);
125 if (options.
bound.has_value()) {
126 auto bound = *(options.
bound);
127 Index_ counter = top;
128 while (counter > 0) {
130 auto pos = semi_sorted[counter];
131 if (cmp(statistic[pos], bound)) {
132 if constexpr(keep_index_) {
133 output.push_back(pos);
140 if constexpr(keep_index_) {
141 output.insert(output.end(), semi_sorted.begin(), semi_sorted.begin() + top);
143 for (
decltype(top) i = 0; i < top; ++i) {
144 output[semi_sorted[i]] =
true;
149 if constexpr(keep_index_) {
150 std::sort(output.begin(), output.end());
178template<
typename Stat_,
typename Top_,
typename Bool_>
181 internal::pick_top_genes<false>(
186 [](Stat_ l, Stat_ r) ->
bool {
return l > r; },
187 [](Stat_ l, Stat_ r) ->
bool {
return l >= r; },
191 internal::pick_top_genes<false>(
196 [](Stat_ l, Stat_ r) ->
bool {
return l < r; },
197 [](Stat_ l, Stat_ r) ->
bool {
return l <= r; },
216template<
typename Bool_,
typename Stat_,
typename Top_>
218 auto output = sanisizer::create<std::vector<Bool_> >(n
219#ifdef SCRAN_VARIANCES_TEST_INIT
220 , SCRAN_VARIANCES_TEST_INIT
223 pick_top_genes(n, statistic, top, larger, output.data(), options);
241template<
typename Index_,
typename Stat_,
typename Top_>
243 std::vector<Index_> output;
245 internal::pick_top_genes<true>(
250 [](Stat_ l, Stat_ r) ->
bool {
return l > r; },
251 [](Stat_ l, Stat_ r) ->
bool {
return l >= r; },
255 internal::pick_top_genes<true>(
260 [](Stat_ l, Stat_ r) ->
bool {
return l < r; },
261 [](Stat_ l, Stat_ r) ->
bool {
return l <= r; },
Options for pick_top_genes().
Definition topicks.hpp:23
bool keep_ties
Definition topicks.hpp:35
std::optional< Stat_ > bound
Definition topicks.hpp:29
std::vector< Index_ > pick_top_genes_index(Index_ n, const Stat_ *statistic, Top_ top, bool larger, const PickTopGenesOptions< Stat_ > &options)
Definition topicks.hpp:242
void pick_top_genes(std::size_t n, const Stat_ *statistic, Top_ top, bool larger, Bool_ *output, const PickTopGenesOptions< Stat_ > &options)
Definition topicks.hpp:179