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
13namespace tatami_stats {
14
27template<typename Group_>
28size_t total_groups(const Group_* group, size_t n) {
29 if (n) {
30 return static_cast<size_t>(*std::max_element(group, group + n)) + 1;
31 } else {
32 return 0;
33 }
34}
35
48template<typename Group_, typename Size_>
49std::vector<Size_> tabulate_groups(const Group_* group, Size_ n) {
50 auto ngroups = total_groups(group, n);
51 std::vector<Size_> group_sizes(ngroups);
52 for (Size_ r = 0; r < n; ++r) {
53 ++(group_sizes[group[r]]);
54 }
55 return group_sizes;
56}
57
77template<typename Output_>
79public:
88 template<typename Index_>
89 LocalOutputBuffer(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) {
90 if (!use_local) {
91 // Setting to zero to match the initial behavior of 'my_buffer' when 'use_local = true'.
92 std::fill_n(my_output, length, fill);
93 }
94 }
95
105 template<typename Index_>
106 LocalOutputBuffer(size_t thread, Index_ start, Index_ length, Output_* output) : LocalOutputBuffer(thread, start, length, output, 0) {}
107
111 LocalOutputBuffer() = default;
112
118 Output_* data() {
119 return (use_local ? my_buffer.data() : my_output);
120 }
121
127 const Output_* data() const {
128 return (use_local ? my_buffer.data() : my_output);
129 }
130
135 void transfer() {
136 if (use_local) {
137 std::copy(my_buffer.begin(), my_buffer.end(), my_output);
138 }
139 }
140
141private:
142 Output_* my_output = NULL;
143 bool use_local = false;
144 std::vector<Output_> my_buffer;
145};
146
147
158template<typename Output_, class GetOutput_>
160public:
170 template<typename Index_>
171 LocalOutputBuffers(size_t thread, size_t number, Index_ start, Index_ length, GetOutput_ outfun, Output_ fill) :
172 my_number(number),
173 my_start(start),
174 my_use_local(thread > 0),
175 my_getter(std::move(outfun))
176 {
177 if (thread == 0) {
178 for (size_t i = 0; i < my_number; ++i) {
179 // Setting to the fill to match the initial behavior of 'my_buffer' when 'thread > 0'.
180 std::fill_n(my_getter(i) + my_start, length, fill);
181 }
182 } else {
183 my_buffers.reserve(my_number);
184 for (size_t i = 0; i < my_number; ++i) {
185 my_buffers.emplace_back(length, fill);
186 }
187 }
188 }
189
200 template<typename Index_>
201 LocalOutputBuffers(size_t thread, size_t number, Index_ start, Index_ length, GetOutput_ outfun) :
202 LocalOutputBuffers(thread, number, start, length, std::move(outfun), 0) {}
203
208
213 size_t size() const {
214 return my_number;
215 }
216
223 Output_* data(size_t i) {
224 return (my_use_local ? my_buffers[i].data() : my_getter(i) + my_start);
225 }
226
233 const Output_* data(size_t i) const {
234 return (my_use_local ? my_buffers[i].data() : my_getter(i) + my_start);
235 }
236
241 void transfer() {
242 if (my_use_local) {
243 for (size_t i = 0; i < my_number; ++i) {
244 const auto& current = my_buffers[i];
245 std::copy(current.begin(), current.end(), my_getter(i) + my_start);
246 }
247 }
248 }
249
250private:
251 size_t my_number = 0;
252 size_t my_start = 0;
253 bool my_use_local = true;
254 std::vector<std::vector<Output_> > my_buffers;
255 GetOutput_ my_getter;
256};
257
261namespace internal {
262
263template<typename Value_, class If_, class Else_>
264void nanable_ifelse(bool skip_nan, If_ iffun, Else_ elsefun) {
265 if constexpr(std::numeric_limits<Value_>::has_quiet_NaN) {
266 if (skip_nan) {
267 iffun();
268 return;
269 }
270 }
271 elsefun();
272}
273
274template<typename Value_, class If_, class Else_>
275auto nanable_ifelse_with_value(bool skip_nan, If_ iffun, Else_ elsefun) {
276 if constexpr(std::numeric_limits<Value_>::has_quiet_NaN) {
277 if (skip_nan) {
278 return iffun();
279 }
280 }
281 return elsefun();
282}
283
284}
289}
290
291#endif
Local output buffer for running calculations.
Definition utils.hpp:78
LocalOutputBuffer(size_t thread, Index_ start, Index_ length, Output_ *output, Output_ fill)
Definition utils.hpp:89
void transfer()
Definition utils.hpp:135
Output_ * data()
Definition utils.hpp:118
const Output_ * data() const
Definition utils.hpp:127
LocalOutputBuffer(size_t thread, Index_ start, Index_ length, Output_ *output)
Definition utils.hpp:106
Local output buffers for running calculations.
Definition utils.hpp:159
void transfer()
Definition utils.hpp:241
const Output_ * data(size_t i) const
Definition utils.hpp:233
LocalOutputBuffers(size_t thread, size_t number, Index_ start, Index_ length, GetOutput_ outfun)
Definition utils.hpp:201
size_t size() const
Definition utils.hpp:213
LocalOutputBuffers(size_t thread, size_t number, Index_ start, Index_ length, GetOutput_ outfun, Output_ fill)
Definition utils.hpp:171
Output_ * data(size_t i)
Definition utils.hpp:223
Functions to compute statistics from a tatami::Matrix.
Definition counts.hpp:18
size_t total_groups(const Group_ *group, size_t n)
Definition utils.hpp:28
std::vector< Size_ > tabulate_groups(const Group_ *group, Size_ n)
Definition utils.hpp:49