tatami_stats
Matrix statistics for tatami
Loading...
Searching...
No Matches
counts.hpp
Go to the documentation of this file.
1#ifndef TATAMI_STATS_COUNTS_HPP
2#define TATAMI_STATS_COUNTS_HPP
3
4#include "tatami/tatami.hpp"
5#include "subpar/subpar.hpp"
6
7#include <vector>
8#include <algorithm>
9#include <cmath>
10#include <type_traits>
11
18namespace tatami_stats {
19
24namespace counts {
25
43template<typename Value_, typename Index_, typename Output_, class Condition_>
44void apply(bool row, const tatami::Matrix<Value_, Index_>& mat, Output_* output, int num_threads, Condition_ condition) {
45 auto dim = (row ? mat.nrow() : mat.ncol());
46 auto otherdim = (row ? mat.ncol() : mat.nrow());
47 std::fill(output, output + dim, 0);
48
49 if (mat.prefer_rows() == row) {
50 if (mat.sparse()) {
52 opt.sparse_ordered_index = false;
53 bool count_zero = condition(0);
54
55 tatami::parallelize([&](int, Index_ start, Index_ len) -> void {
56 std::vector<Value_> xbuffer(otherdim);
57 std::vector<Index_> ibuffer(otherdim);
58 auto ext = tatami::consecutive_extractor<true>(mat, row, start, len, opt);
59
60 for (Index_ x = 0; x < len; ++x) {
61 auto range = ext->fetch(xbuffer.data(), ibuffer.data());
62 Output_ target = 0;
63 for (Index_ j = 0; j < range.number; ++j) {
64 target += condition(range.value[j]);
65 }
66 if (count_zero) {
67 target += otherdim - range.number;
68 }
69 output[x + start] = target;
70 }
71 }, dim, num_threads);
72
73 } else {
74 tatami::parallelize([&](int, Index_ start, Index_ len) -> void {
75 std::vector<Value_> xbuffer(otherdim);
76 auto ext = tatami::consecutive_extractor<false>(mat, row, start, len);
77
78 for (Index_ x = 0; x < len; ++x) {
79 auto ptr = ext->fetch(xbuffer.data());
80 Output_ target = 0;
81 for (Index_ j = 0; j < otherdim; ++j) {
82 target += condition(ptr[j]);
83 }
84 output[x + start] = target;
85 }
86 }, dim, num_threads);
87 }
88
89 } else {
90 std::vector<std::vector<Output_> > threaded_output(num_threads > 0 ? num_threads - 1 : 0);
91
92 if (mat.sparse()) {
94 opt.sparse_ordered_index = false;
95 bool count_zero = condition(0);
96
97 tatami::parallelize([&](int thread, Index_ start, Index_ len) -> void {
98 std::vector<Value_> xbuffer(dim);
99 std::vector<Index_> ibuffer(dim);
100 auto ext = tatami::consecutive_extractor<true>(mat, !row, start, len, opt);
101
102 auto curoutput = output;
103 if (thread) {
104 auto& outvec = threaded_output[thread - 1];
105 outvec.resize(dim);
106 curoutput = outvec.data();
107 }
108 std::vector<Index_> nonzeros(dim);
109
110 for (Index_ x = 0; x < len; ++x) {
111 auto range = ext->fetch(xbuffer.data(), ibuffer.data());
112 for (Index_ j = 0; j < range.number; ++j) {
113 auto idx = range.index[j];
114 curoutput[idx] += condition(range.value[j]);
115 ++(nonzeros[idx]);
116 }
117 }
118
119 if (count_zero) {
120 for (int d = 0; d < dim; ++d) {
121 curoutput[d] += len - nonzeros[d];
122 }
123 }
124 }, otherdim, num_threads);
125
126 } else {
127 tatami::parallelize([&](int thread, Index_ start, Index_ len) -> void {
128 std::vector<Value_> xbuffer(dim);
129 auto ext = tatami::consecutive_extractor<false>(mat, !row, start, len);
130
131 auto curoutput = output;
132 if (thread) {
133 auto& outvec = threaded_output[thread - 1];
134 outvec.resize(dim);
135 curoutput = outvec.data();
136 }
137
138 for (Index_ x = 0; x < len; ++x) {
139 auto ptr = ext->fetch(xbuffer.data());
140 for (Index_ j = 0; j < dim; ++j) {
141 curoutput[j] += condition(ptr[j]);
142 }
143 }
144 }, otherdim, num_threads);
145 }
146
147 for (const auto& curout : threaded_output) {
148 if (!curout.empty()) {
149 for (Index_ d = 0; d < dim; ++d) {
150 output[d] += curout[d];
151 }
152 }
153 }
154 }
155}
156
160// Back-compatibility only.
161template<typename Value_, typename Index_, typename Output_, class Condition_>
162void apply(bool row, const tatami::Matrix<Value_, Index_>* p, Output_* output, int num_threads, Condition_ condition) {
163 apply(row, *p, output, num_threads, std::move(condition));
164}
173namespace nan {
174
178struct Options {
183 int num_threads = 1;
184
185};
186
199template<typename Value_, typename Index_, typename Output_>
200void apply(bool row, const tatami::Matrix<Value_, Index_>& mat, Output_* output, const Options& nopt) {
201 counts::apply(row, mat, output, nopt.num_threads, [](Value_ x) -> bool { return std::isnan(x); });
202}
203
207// Back-compatibility only.
208template<typename Value_, typename Index_, typename Output_>
209void apply(bool row, const tatami::Matrix<Value_, Index_>* p, Output_* output, const Options& nopt) {
210 apply(row, *p, output, nopt);
211}
228template<typename Output_ = int, typename Value_, typename Index_>
229std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>& mat, const Options& nopt) {
230 std::vector<Output_> output(mat.nrow());
231 apply(true, mat, output.data(), nopt);
232 return output;
233}
234
238// Back-compatibility only.
239template<typename Output_ = int, typename Value_, typename Index_>
240std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>* p, const Options& nopt) {
241 return by_row<Output_>(*p, nopt);
242}
257template<typename Output_ = int, typename Value_, typename Index_>
258std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>& mat) {
259 return by_row<Output_>(mat, Options());
260}
261
265// Back-compatibility only.
266template<typename Output_ = int, typename Value_, typename Index_>
267std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>* p) {
268 return by_row<Output_>(*p);
269}
287template<typename Output_ = int, typename Value_, typename Index_>
288std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>& mat, const Options& nopt) {
289 std::vector<Output_> output(mat.ncol());
290 apply(false, mat, output.data(), nopt);
291 return output;
292}
293
297// Back-compatibility only.
298template<typename Output_ = int, typename Value_, typename Index_>
299std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>* p, const Options& nopt) {
300 return by_column<Output_>(*p, nopt);
301}
318template<typename Output_ = int, typename Value_, typename Index_>
319std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>& mat) {
320 return by_column<Output_>(mat, Options());
321}
322
326// Back-compatibility only.
327template<typename Output_ = int, typename Value_, typename Index_>
328std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>* p) {
329 return by_column<Output_>(*p);
330}
335}
336
341namespace zero {
342
346struct Options {
351 int num_threads = 1;
352};
353
366template<typename Value_, typename Index_, typename Output_>
367void apply(bool row, const tatami::Matrix<Value_, Index_>& mat, Output_* output, const Options& zopt) {
368 counts::apply(row, mat, output, zopt.num_threads, [](Value_ x) -> bool { return x == 0; });
369}
370
374// Back-compatibility.
375template<typename Value_, typename Index_, typename Output_>
376void apply(bool row, const tatami::Matrix<Value_, Index_>* p, Output_* output, const Options& zopt) {
377 apply(row, *p, output, zopt);
378}
394template<typename Output_ = int, typename Value_, typename Index_>
395std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>& mat, const Options& zopt) {
396 std::vector<Output_> output(mat.nrow());
397 apply(true, mat, output.data(), zopt);
398 return output;
399}
400
404// Back-compatibility.
405template<typename Output_ = int, typename Value_, typename Index_>
406std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>* p, const Options& zopt) {
407 return by_row<Output_>(*p, zopt);
408}
425template<typename Output_ = int, typename Value_, typename Index_>
426std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>& mat) {
427 return by_row<Output_>(mat, Options());
428}
429
433// Back-compatibility.
434template<typename Output_ = int, typename Value_, typename Index_>
435std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>* p) {
436 return by_row<Output_>(*p);
437}
455template<typename Output_ = int, typename Value_, typename Index_>
456std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>& mat, const Options& zopt) {
457 std::vector<Output_> output(mat.ncol());
458 apply(false, mat, output.data(), zopt);
459 return output;
460}
461
465// Back-compatibility.
466template<typename Output_ = int, typename Value_, typename Index_>
467std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>* p, const Options& zopt) {
468 return by_column<Output_>(*p, zopt);
469}
484template<typename Output_ = int, typename Value_, typename Index_>
485std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>& mat) {
486 return by_column<Output_>(mat, Options());
487}
488
492// Back-compatibility.
493template<typename Output_ = int, typename Value_, typename Index_>
494std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>* p) {
495 return by_column<Output_>(*p);
496}
501}
502
503}
504
505}
506
507#endif
virtual Index_ ncol() const=0
virtual Index_ nrow() const=0
virtual bool prefer_rows() const=0
virtual std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, const Options &opt) const=0
std::vector< Output_ > by_row(const tatami::Matrix< Value_, Index_ > &mat, const Options &nopt)
Definition counts.hpp:229
std::vector< Output_ > by_column(const tatami::Matrix< Value_, Index_ > &mat, const Options &nopt)
Definition counts.hpp:288
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *output, const Options &nopt)
Definition counts.hpp:200
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *output, const Options &zopt)
Definition counts.hpp:367
std::vector< Output_ > by_column(const tatami::Matrix< Value_, Index_ > &mat, const Options &zopt)
Definition counts.hpp:456
std::vector< Output_ > by_row(const tatami::Matrix< Value_, Index_ > &mat, const Options &zopt)
Definition counts.hpp:395
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *output, int num_threads, Condition_ condition)
Definition counts.hpp:44
Functions to compute statistics from a tatami::Matrix.
Definition counts.hpp:18
void parallelize(Function_ fun, Index_ tasks, int threads)
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, bool row, Index_ iter_start, Index_ iter_length, Args_ &&... args)
bool sparse_ordered_index
NaN-counting options.
Definition counts.hpp:178
int num_threads
Definition counts.hpp:183
Zero-counting options.
Definition counts.hpp:346
int num_threads
Definition counts.hpp:351