36template<
typename Value_,
typename Index_,
typename Output_,
class Condition_>
38 const Index_ dim = (row ? mat.
nrow() : mat.
ncol());
39 const Index_ otherdim = (row ? mat.
ncol() : mat.
nrow());
44 const bool count_zero = condition(0);
51 for (Index_ x = 0; x < len; ++x) {
52 auto range = ext->fetch(xbuffer.data(), ibuffer.data());
54 for (Index_ j = 0; j <
range.number; ++j) {
55 target += condition(
range.value[j]);
58 target += otherdim -
range.number;
60 output[x + start] = target;
69 for (Index_ x = 0; x < len; ++x) {
70 auto ptr = ext->fetch(xbuffer.data());
72 for (Index_ j = 0; j < otherdim; ++j) {
73 target += condition(ptr[j]);
75 output[x + start] = target;
81template<
typename Value_,
typename Index_,
typename Output_,
class Condition_>
82void count_running(
const bool row,
const tatami::Matrix<Value_, Index_>& mat, Output_*
const output, Condition_ condition,
const CountOptions& opt) {
83 const Index_ dim = (row ? mat.
nrow() : mat.
ncol());
84 const Index_ otherdim = (row ? mat.
ncol() : mat.
nrow());
87 std::optional<std::vector<std::optional<std::vector<Output_> > > > all_partial_count;
89 all_partial_count.emplace(sanisizer::cast<I<
decltype(all_partial_count->size())> >(opt.num_threads - 1));
94 const bool count_zero = is_sparse && condition(0);
96 std::fill_n(output, dim, 0);
98 const int num_used =
tatami::parallelize([&](
int thread, Index_ start, Index_ len) ->
void {
100 std::optional<std::vector<Output_> > cur_count;
110 out_ptr = cur_count->data();
122 for (Index_ x = 0; x < len; ++x) {
123 auto range = ext->fetch(xbuffer.data(), ibuffer.data());
124 for (Index_ j = 0; j <
range.number; ++j) {
125 auto idx =
range.index[j];
126 out_ptr[idx] += condition(
range.value[j]);
132 for (Index_ d = 0; d < dim; ++d) {
133 out_ptr[d] += len - nonzeros[d];
141 for (Index_ x = 0; x < len; ++x) {
142 auto ptr = ext->fetch(xbuffer.data());
143 for (Index_ d = 0; d < dim; ++d) {
144 out_ptr[d] += condition(ptr[d]);
150 (*all_partial_count)[thread - 1] = std::move(cur_count);
152 }, otherdim, opt.num_threads);
156 for (
int u = 1; u < num_used; ++u) {
157 const auto& curout = *((*all_partial_count)[u - 1]);
158 for (Index_ d = 0; d < dim; ++d) {
159 output[d] += curout[d];
187template<
typename Value_,
typename Index_,
typename Output_,
class Condition_>
190 count_direct(row, mat, output, std::move(condition), opt);
192 count_running(row, mat, output, std::move(condition), opt);
213template<
typename Output_,
typename Value_,
typename Index_,
class Condition_>
215 const Index_ dim = (row ? mat.
nrow() : mat.
ncol());
216 auto output = sanisizer::create<std::vector<Output_> >(dim
217#ifdef TATAMI_STATS_TEST_DIRTY
221 count(row, mat, output.data(), std::move(condition), opt);
void range(bool row, const tatami::Matrix< Value_, Index_ > &mat, RangeBuffers< Output_ > &output, const RangeOptions &opt)
Definition range.hpp:400
void count(const bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *const output, Condition_ condition, const CountOptions &opt)
Definition count.hpp:188
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, const Index_ iter_start, const Index_ iter_length, Args_ &&... args)