1#ifndef TATAMI_STATS_RANGES_HPP
2#define TATAMI_STATS_RANGES_HPP
48template<
typename Value_>
49constexpr Value_ choose_minimum_placeholder() {
51 if constexpr(std::numeric_limits<Value_>::has_infinity) {
52 return std::numeric_limits<Value_>::infinity();
54 return std::numeric_limits<Value_>::max();
58template<
typename Value_>
59constexpr Value_ choose_maximum_placeholder() {
61 if constexpr(std::numeric_limits<Value_>::has_infinity) {
62 return -std::numeric_limits<Value_>::infinity();
64 return std::numeric_limits<Value_>::lowest();
89template<
typename Value_,
typename Index_>
90Value_
direct(
const Value_* ptr, Index_ num,
bool minimum,
bool skip_nan) {
91 return ::tatami_stats::internal::nanable_ifelse_with_value<Value_>(
96 auto current = internal::choose_minimum_placeholder<Value_>();
97 for (Index_ i = 0; i < num; ++i) {
105 auto current = internal::choose_maximum_placeholder<Value_>();
106 for (Index_ i = 0; i < num; ++i) {
119 return *std::min_element(ptr, ptr + num);
121 return *std::max_element(ptr, ptr + num);
125 return internal::choose_minimum_placeholder<Value_>();
127 return internal::choose_maximum_placeholder<Value_>();
152template<
typename Value_,
typename Index_>
153Value_
direct(
const Value_* value, Index_ num_nonzero, Index_ num_all,
bool minimum,
bool skip_nan) {
155 auto candidate =
direct(value, num_nonzero, minimum, skip_nan);
156 if (num_nonzero < num_all) {
169 }
else if (num_all) {
174 return internal::choose_minimum_placeholder<Value_>();
176 return internal::choose_maximum_placeholder<Value_>();
194template<
typename Output_,
typename Value_,
typename Index_>
207 RunningDense(Index_ num, Output_* store_min, Output_* store_max,
bool skip_nan) :
208 my_num(num), my_store_min(store_min), my_store_max(store_max), my_skip_nan(skip_nan) {}
214 void add(
const Value_* ptr) {
217 ::tatami_stats::internal::nanable_ifelse<Value_>(
222 for (Index_ i = 0; i < my_num; ++i) {
224 if (std::isnan(val)) {
225 my_store_min[i] = internal::choose_minimum_placeholder<Value_>();
227 my_store_min[i] = val;
232 for (Index_ i = 0; i < my_num; ++i) {
234 if (std::isnan(val)) {
235 my_store_max[i] = internal::choose_maximum_placeholder<Value_>();
237 my_store_max[i] = val;
245 std::copy_n(ptr, my_num, my_store_min);
248 std::copy_n(ptr, my_num, my_store_max);
255 for (Index_ i = 0; i < my_num; ++i) {
257 auto& current = my_store_min[i];
264 for (Index_ i = 0; i < my_num; ++i) {
266 auto& current = my_store_max[i];
281 std::fill_n(my_store_min, my_num, internal::choose_minimum_placeholder<Value_>());
284 std::fill_n(my_store_max, my_num, internal::choose_maximum_placeholder<Value_>());
292 Output_* my_store_min;
293 Output_* my_store_max;
307template<
typename Output_,
typename Value_,
typename Index_>
323 RunningSparse(Index_ num, Output_* store_min, Output_* store_max,
bool skip_nan, Index_ subtract = 0) :
324 my_num(num), my_store_min(store_min), my_store_max(store_max), my_skip_nan(skip_nan), my_subtract(subtract) {}
332 void add(
const Value_* value,
const Index_* index, Index_ number) {
337 std::fill_n(my_store_min, my_num, internal::choose_minimum_placeholder<Value_>());
340 std::fill_n(my_store_max, my_num, internal::choose_maximum_placeholder<Value_>());
344 for (Index_ i = 0; i < number; ++i) {
346 auto idx = index[i] - my_subtract;
348 my_store_min[idx] = val;
351 my_store_max[idx] = val;
360 for (Index_ i = 0; i < number; ++i) {
362 auto idx = index[i] - my_subtract;
364 auto& current = my_store_min[idx];
370 auto& current = my_store_max[idx];
386 for (Index_ i = 0; i < my_num; ++i) {
387 if (my_count > my_nonzero[i]) {
389 auto& current = my_store_min[i];
395 auto& current = my_store_max[i];
404 std::fill_n(my_store_min, my_num, internal::choose_minimum_placeholder<Value_>());
407 std::fill_n(my_store_max, my_num, internal::choose_maximum_placeholder<Value_>());
414 Output_* my_store_min;
415 Output_* my_store_max;
419 std::vector<Index_> my_nonzero;
440template<
typename Value_,
typename Index_,
typename Output_>
442 auto dim = (row ? mat.
nrow() : mat.
ncol());
443 auto otherdim = (row ? mat.
ncol() : mat.
nrow());
446 bool store_min = min_out != NULL;
447 bool store_max = max_out != NULL;
458 for (Index_ x = 0; x < l; ++x) {
459 auto out = ext->fetch(vbuffer.data(), NULL);
479 for (Index_ x = 0; x < otherdim; ++x) {
480 auto out = ext->fetch(vbuffer.data(), ibuffer.data());
481 runner.
add(out.value, out.index, out.number);
486 local_min.transfer();
489 local_max.transfer();
499 for (Index_ x = 0; x < l; ++x) {
500 auto ptr = ext->fetch(buffer.data());
519 for (Index_ x = 0; x < otherdim; ++x) {
520 auto ptr = ext->fetch(buffer.data());
526 local_min.transfer();
529 local_max.transfer();
542template<
typename Value_,
typename Index_,
typename Output_>
544 apply(row, *p, min_out, max_out, ropt);
563template<
typename Output_ =
double,
typename Value_,
typename Index_>
567 apply(
false, mat, mins.data(), maxs.data(), ropt);
568 return std::make_pair(std::move(mins), std::move(maxs));
575template<
typename Output_ =
double,
typename Value_,
typename Index_>
580template<
typename Output_ =
double,
typename Value_,
typename Index_>
585template<
typename Output_ =
double,
typename Value_,
typename Index_>
606template<
typename Output_ =
double,
typename Value_,
typename Index_>
610 apply(
true, mat, mins.data(), maxs.data(), ropt);
611 return std::make_pair(std::move(mins), std::move(maxs));
618template<
typename Output_ =
double,
typename Value_,
typename Index_>
623template<
typename Output_ =
double,
typename Value_,
typename Index_>
628template<
typename Output_ =
double,
typename Value_,
typename Index_>
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
Local output buffer for running calculations.
Definition utils.hpp:82
Running minima/maxima from dense data.
Definition ranges.hpp:195
void add(const Value_ *ptr)
Definition ranges.hpp:214
void finish()
Definition ranges.hpp:278
RunningDense(Index_ num, Output_ *store_min, Output_ *store_max, bool skip_nan)
Definition ranges.hpp:207
Running minima/maxima from sparse data.
Definition ranges.hpp:308
void finish()
Definition ranges.hpp:384
void add(const Value_ *value, const Index_ *index, Index_ number)
Definition ranges.hpp:332
RunningSparse(Index_ num, Output_ *store_min, Output_ *store_max, bool skip_nan, Index_ subtract=0)
Definition ranges.hpp:323
std::pair< std::vector< Output_ >, std::vector< Output_ > > by_row(const tatami::Matrix< Value_, Index_ > &mat, const Options &ropt)
Definition ranges.hpp:607
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *min_out, Output_ *max_out, const Options &ropt)
Definition ranges.hpp:441
std::pair< std::vector< Output_ >, std::vector< Output_ > > by_column(const tatami::Matrix< Value_, Index_ > &mat, const Options &ropt)
Definition ranges.hpp:564
Value_ direct(const Value_ *ptr, Index_ num, bool minimum, bool skip_nan)
Definition ranges.hpp:90
Functions to compute statistics from a tatami::Matrix.
Definition counts.hpp:18
void parallelize(Function_ fun, Index_ tasks, int threads)
void resize_container_to_Index_size(Container_ &container, Index_ x, Args_ &&... args)
Container_ create_container_of_Index_size(Index_ x, Args_ &&... args)
auto consecutive_extractor(const Matrix< Value_, Index_ > &matrix, bool row, Index_ iter_start, Index_ iter_length, Args_ &&... args)
bool sparse_extract_index
bool sparse_ordered_index
Range calculation options.
Definition ranges.hpp:29
bool skip_nan
Definition ranges.hpp:34
int num_threads
Definition ranges.hpp:40
Utilities for computing matrix statistics.