tatami_stats
Matrix statistics for tatami
Loading...
Searching...
No Matches
utils.hpp
Go to the documentation of this file.
1#ifndef TATAMI_STATS__UTILS_HPP
2#define TATAMI_STATS__UTILS_HPP
3
4#include <vector>
5#include <algorithm>
6#include <cstddef>
7
14namespace tatami_stats {
15
28template<typename Group_>
29std::size_t total_groups(const Group_* group, std::size_t n) {
30 if (n) {
31 return static_cast<std::size_t>(*std::max_element(group, group + n)) + 1;
32 } else {
33 return 0;
34 }
35}
36
49template<typename Group_, typename Size_>
50std::vector<Size_> tabulate_groups(const Group_* group, Size_ n) {
51 auto ngroups = total_groups(group, n);
52 std::vector<Size_> group_sizes(ngroups);
53 for (Size_ r = 0; r < n; ++r) {
54 ++(group_sizes[group[r]]);
55 }
56 return group_sizes;
57}
58
78template<typename Output_>
80public:
89 template<typename Index_>
90 LocalOutputBuffer(std::size_t thread, Index_ start, Index_ length, Output_* output, Output_ fill) : my_output(output + start), use_local(thread > 0), my_buffer(use_local ? length : 0, fill) {
91 if (!use_local) {
92 // Setting to zero to match the initial behavior of 'my_buffer' when 'use_local = true'.
93 std::fill_n(my_output, length, fill);
94 }
95 }
96
106 template<typename Index_>
107 LocalOutputBuffer(std::size_t thread, Index_ start, Index_ length, Output_* output) : LocalOutputBuffer(thread, start, length, output, 0) {}
108
112 LocalOutputBuffer() = default;
113
119 Output_* data() {
120 return (use_local ? my_buffer.data() : my_output);
121 }
122
128 const Output_* data() const {
129 return (use_local ? my_buffer.data() : my_output);
130 }
131
136 void transfer() {
137 if (use_local) {
138 std::copy(my_buffer.begin(), my_buffer.end(), my_output);
139 }
140 }
141
142private:
143 Output_* my_output = NULL;
144 bool use_local = false;
145 std::vector<Output_> my_buffer;
146};
147
148
159template<typename Output_, class GetOutput_>
161public:
171 template<typename Index_>
172 LocalOutputBuffers(std::size_t thread, std::size_t number, Index_ start, Index_ length, GetOutput_ outfun, Output_ fill) :
173 my_number(number),
174 my_start(start),
175 my_use_local(thread > 0),
176 my_getter(std::move(outfun))
177 {
178 if (thread == 0) {
179 for (decltype(my_number) i = 0; i < my_number; ++i) {
180 // Setting to the fill to match the initial behavior of 'my_buffer' when 'thread > 0'.
181 std::fill_n(my_getter(i) + my_start, length, fill);
182 }
183 } else {
184 my_buffers.reserve(my_number);
185 for (decltype(my_number) i = 0; i < my_number; ++i) {
186 my_buffers.emplace_back(length, fill);
187 }
188 }
189 }
190
201 template<typename Index_>
202 LocalOutputBuffers(std::size_t thread, std::size_t number, Index_ start, Index_ length, GetOutput_ outfun) :
203 LocalOutputBuffers(thread, number, start, length, std::move(outfun), 0) {}
204
209
214 std::size_t size() const {
215 return my_number;
216 }
217
224 Output_* data(std::size_t i) {
225 return (my_use_local ? my_buffers[i].data() : my_getter(i) + my_start);
226 }
227
234 const Output_* data(std::size_t i) const {
235 return (my_use_local ? my_buffers[i].data() : my_getter(i) + my_start);
236 }
237
242 void transfer() {
243 if (my_use_local) {
244 for (decltype(my_number) i = 0; i < my_number; ++i) {
245 const auto& current = my_buffers[i];
246 std::copy(current.begin(), current.end(), my_getter(i) + my_start);
247 }
248 }
249 }
250
251private:
252 std::size_t my_number = 0;
253 std::size_t my_start = 0;
254 bool my_use_local = true;
255 std::vector<std::vector<Output_> > my_buffers;
256 GetOutput_ my_getter;
257};
258
262namespace internal {
263
264template<typename Value_, class If_, class Else_>
265void nanable_ifelse(bool skip_nan, If_ iffun, Else_ elsefun) {
266 if constexpr(std::numeric_limits<Value_>::has_quiet_NaN) {
267 if (skip_nan) {
268 iffun();
269 return;
270 }
271 }
272 elsefun();
273}
274
275template<typename Value_, class If_, class Else_>
276auto nanable_ifelse_with_value(bool skip_nan, If_ iffun, Else_ elsefun) {
277 if constexpr(std::numeric_limits<Value_>::has_quiet_NaN) {
278 if (skip_nan) {
279 return iffun();
280 }
281 }
282 return elsefun();
283}
284
285}
290}
291
292#endif
Local output buffer for running calculations.
Definition utils.hpp:79
void transfer()
Definition utils.hpp:136
Output_ * data()
Definition utils.hpp:119
LocalOutputBuffer(std::size_t thread, Index_ start, Index_ length, Output_ *output, Output_ fill)
Definition utils.hpp:90
const Output_ * data() const
Definition utils.hpp:128
LocalOutputBuffer(std::size_t thread, Index_ start, Index_ length, Output_ *output)
Definition utils.hpp:107
Local output buffers for running calculations.
Definition utils.hpp:160
LocalOutputBuffers(std::size_t thread, std::size_t number, Index_ start, Index_ length, GetOutput_ outfun, Output_ fill)
Definition utils.hpp:172
const Output_ * data(std::size_t i) const
Definition utils.hpp:234
void transfer()
Definition utils.hpp:242
std::size_t size() const
Definition utils.hpp:214
Output_ * data(std::size_t i)
Definition utils.hpp:224
LocalOutputBuffers(std::size_t thread, std::size_t number, Index_ start, Index_ length, GetOutput_ outfun)
Definition utils.hpp:202
Functions to compute statistics from a tatami::Matrix.
Definition counts.hpp:18
std::size_t total_groups(const Group_ *group, std::size_t n)
Definition utils.hpp:29
std::vector< Size_ > tabulate_groups(const Group_ *group, Size_ n)
Definition utils.hpp:50