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 <vector>
5#include <algorithm>
6#include <cmath>
7#include <type_traits>
8
9#include "tatami/tatami.hpp"
10#include "sanisizer/sanisizer.hpp"
11
18namespace tatami_stats {
19
24namespace counts {
25
44template<typename Value_, typename Index_, typename Output_, class Condition_>
45void apply(bool row, const tatami::Matrix<Value_, Index_>& mat, Output_* output, int num_threads, Condition_ condition) {
46 const Index_ dim = (row ? mat.nrow() : mat.ncol());
47 const Index_ otherdim = (row ? mat.ncol() : mat.nrow());
48 std::fill(output, output + dim, 0);
49
50 if (mat.prefer_rows() == row) {
51 if (mat.sparse()) {
53 opt.sparse_ordered_index = false;
54 bool count_zero = condition(0);
55
56 tatami::parallelize([&](int, Index_ start, Index_ len) -> void {
59 auto ext = tatami::consecutive_extractor<true>(mat, row, start, len, opt);
60
61 for (Index_ x = 0; x < len; ++x) {
62 auto range = ext->fetch(xbuffer.data(), ibuffer.data());
63 Output_ target = 0;
64 for (Index_ j = 0; j < range.number; ++j) {
65 target += condition(range.value[j]);
66 }
67 if (count_zero) {
68 target += otherdim - range.number;
69 }
70 output[x + start] = target;
71 }
72 }, dim, num_threads);
73
74 } else {
75 tatami::parallelize([&](int, Index_ start, Index_ len) -> void {
77 auto ext = tatami::consecutive_extractor<false>(mat, row, start, len);
78
79 for (Index_ x = 0; x < len; ++x) {
80 auto ptr = ext->fetch(xbuffer.data());
81 Output_ target = 0;
82 for (Index_ j = 0; j < otherdim; ++j) {
83 target += condition(ptr[j]);
84 }
85 output[x + start] = target;
86 }
87 }, dim, num_threads);
88 }
89
90 } else {
91 auto threaded_output = sanisizer::create<std::vector<std::vector<Output_> > >(num_threads > 0 ? num_threads - 1 : 0);
92
93 if (mat.sparse()) {
95 opt.sparse_ordered_index = false;
96 bool count_zero = condition(0);
97
98 tatami::parallelize([&](int thread, Index_ start, Index_ len) -> void {
101 auto ext = tatami::consecutive_extractor<true>(mat, !row, start, len, opt);
102
103 auto curoutput = output;
104 if (thread) {
105 auto& outvec = threaded_output[thread - 1];
106 outvec.resize(dim);
107 curoutput = outvec.data();
108 }
110
111 for (Index_ x = 0; x < len; ++x) {
112 auto range = ext->fetch(xbuffer.data(), ibuffer.data());
113 for (Index_ j = 0; j < range.number; ++j) {
114 auto idx = range.index[j];
115 curoutput[idx] += condition(range.value[j]);
116 ++(nonzeros[idx]);
117 }
118 }
119
120 if (count_zero) {
121 for (Index_ d = 0; d < dim; ++d) {
122 curoutput[d] += len - nonzeros[d];
123 }
124 }
125 }, otherdim, num_threads);
126
127 } else {
128 tatami::parallelize([&](int thread, Index_ start, Index_ len) -> void {
130 auto ext = tatami::consecutive_extractor<false>(mat, !row, start, len);
131
132 auto curoutput = output;
133 if (thread) {
134 auto& outvec = threaded_output[thread - 1];
135 outvec.resize(dim);
136 curoutput = outvec.data();
137 }
138
139 for (Index_ x = 0; x < len; ++x) {
140 auto ptr = ext->fetch(xbuffer.data());
141 for (Index_ j = 0; j < dim; ++j) {
142 curoutput[j] += condition(ptr[j]);
143 }
144 }
145 }, otherdim, num_threads);
146 }
147
148 for (const auto& curout : threaded_output) {
149 if (!curout.empty()) {
150 for (Index_ d = 0; d < dim; ++d) {
151 output[d] += curout[d];
152 }
153 }
154 }
155 }
156}
157
161// Back-compatibility only.
162template<typename Value_, typename Index_, typename Output_, class Condition_>
163void apply(bool row, const tatami::Matrix<Value_, Index_>* p, Output_* output, int num_threads, Condition_ condition) {
164 apply(row, *p, output, num_threads, std::move(condition));
165}
174namespace nan {
175
179struct Options {
184 int num_threads = 1;
185
186};
187
200template<typename Value_, typename Index_, typename Output_>
201void apply(bool row, const tatami::Matrix<Value_, Index_>& mat, Output_* output, const Options& nopt) {
202 counts::apply(row, mat, output, nopt.num_threads, [](Value_ x) -> bool { return std::isnan(x); });
203}
204
208// Back-compatibility only.
209template<typename Value_, typename Index_, typename Output_>
210void apply(bool row, const tatami::Matrix<Value_, Index_>* p, Output_* output, const Options& nopt) {
211 apply(row, *p, output, nopt);
212}
230template<typename Output_ = int, typename Value_, typename Index_>
231std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>& mat, const Options& nopt) {
233 apply(true, mat, output.data(), nopt);
234 return output;
235}
236
240// Back-compatibility only.
241template<typename Output_ = int, typename Value_, typename Index_>
242std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>* p, const Options& nopt) {
243 return by_row<Output_>(*p, nopt);
244}
260template<typename Output_ = int, typename Value_, typename Index_>
261std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>& mat) {
262 return by_row<Output_>(mat, Options());
263}
264
268// Back-compatibility only.
269template<typename Output_ = int, typename Value_, typename Index_>
270std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>* p) {
271 return by_row<Output_>(*p);
272}
290template<typename Output_ = int, typename Value_, typename Index_>
291std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>& mat, const Options& nopt) {
293 apply(false, mat, output.data(), nopt);
294 return output;
295}
296
300// Back-compatibility only.
301template<typename Output_ = int, typename Value_, typename Index_>
302std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>* p, const Options& nopt) {
303 return by_column<Output_>(*p, nopt);
304}
321template<typename Output_ = int, typename Value_, typename Index_>
322std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>& mat) {
323 return by_column<Output_>(mat, Options());
324}
325
329// Back-compatibility only.
330template<typename Output_ = int, typename Value_, typename Index_>
331std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>* p) {
332 return by_column<Output_>(*p);
333}
338}
339
344namespace zero {
345
349struct Options {
354 int num_threads = 1;
355};
356
369template<typename Value_, typename Index_, typename Output_>
370void apply(bool row, const tatami::Matrix<Value_, Index_>& mat, Output_* output, const Options& zopt) {
371 counts::apply(row, mat, output, zopt.num_threads, [](Value_ x) -> bool { return x == 0; });
372}
373
377// Back-compatibility.
378template<typename Value_, typename Index_, typename Output_>
379void apply(bool row, const tatami::Matrix<Value_, Index_>* p, Output_* output, const Options& zopt) {
380 apply(row, *p, output, zopt);
381}
397template<typename Output_ = int, typename Value_, typename Index_>
398std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>& mat, const Options& zopt) {
400 apply(true, mat, output.data(), zopt);
401 return output;
402}
403
407// Back-compatibility.
408template<typename Output_ = int, typename Value_, typename Index_>
409std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>* p, const Options& zopt) {
410 return by_row<Output_>(*p, zopt);
411}
428template<typename Output_ = int, typename Value_, typename Index_>
429std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>& mat) {
430 return by_row<Output_>(mat, Options());
431}
432
436// Back-compatibility.
437template<typename Output_ = int, typename Value_, typename Index_>
438std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>* p) {
439 return by_row<Output_>(*p);
440}
458template<typename Output_ = int, typename Value_, typename Index_>
459std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>& mat, const Options& zopt) {
461 apply(false, mat, output.data(), zopt);
462 return output;
463}
464
468// Back-compatibility.
469template<typename Output_ = int, typename Value_, typename Index_>
470std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>* p, const Options& zopt) {
471 return by_column<Output_>(*p, zopt);
472}
488template<typename Output_ = int, typename Value_, typename Index_>
489std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>& mat) {
490 return by_column<Output_>(mat, Options());
491}
492
496// Back-compatibility.
497template<typename Output_ = int, typename Value_, typename Index_>
498std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>* p) {
499 return by_column<Output_>(*p);
500}
505}
506
507}
508
509}
510
511#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:231
std::vector< Output_ > by_column(const tatami::Matrix< Value_, Index_ > &mat, const Options &nopt)
Definition counts.hpp:291
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *output, const Options &nopt)
Definition counts.hpp:201
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *output, const Options &zopt)
Definition counts.hpp:370
std::vector< Output_ > by_column(const tatami::Matrix< Value_, Index_ > &mat, const Options &zopt)
Definition counts.hpp:459
std::vector< Output_ > by_row(const tatami::Matrix< Value_, Index_ > &mat, const Options &zopt)
Definition counts.hpp:398
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *output, int num_threads, Condition_ condition)
Definition counts.hpp:45
Functions to compute statistics from a tatami::Matrix.
Definition counts.hpp:18
void parallelize(Function_ fun, const Index_ tasks, const int threads)
Container_ create_container_of_Index_size(const Index_ x, Args_ &&... args)
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, const bool row, const Index_ iter_start, const Index_ iter_length, Args_ &&... args)
bool sparse_ordered_index
NaN-counting options.
Definition counts.hpp:179
int num_threads
Definition counts.hpp:184
Zero-counting options.
Definition counts.hpp:349
int num_threads
Definition counts.hpp:354