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_>();
195template<
typename Output_,
typename Value_,
typename Index_>
208 RunningDense(Index_ num, Output_* store_min, Output_* store_max,
bool skip_nan) :
209 my_num(num), my_store_min(store_min), my_store_max(store_max), my_skip_nan(skip_nan) {}
215 void add(
const Value_* ptr) {
218 ::tatami_stats::internal::nanable_ifelse<Value_>(
223 for (Index_ i = 0; i < my_num; ++i) {
225 if (std::isnan(val)) {
226 my_store_min[i] = internal::choose_minimum_placeholder<Value_>();
228 my_store_min[i] = val;
233 for (Index_ i = 0; i < my_num; ++i) {
235 if (std::isnan(val)) {
236 my_store_max[i] = internal::choose_maximum_placeholder<Value_>();
238 my_store_max[i] = val;
246 std::copy_n(ptr, my_num, my_store_min);
249 std::copy_n(ptr, my_num, my_store_max);
256 for (Index_ i = 0; i < my_num; ++i) {
258 auto& current = my_store_min[i];
265 for (Index_ i = 0; i < my_num; ++i) {
267 auto& current = my_store_max[i];
282 std::fill_n(my_store_min, my_num, internal::choose_minimum_placeholder<Value_>());
285 std::fill_n(my_store_max, my_num, internal::choose_maximum_placeholder<Value_>());
293 Output_* my_store_min;
294 Output_* my_store_max;
309template<
typename Output_,
typename Value_,
typename Index_>
325 RunningSparse(Index_ num, Output_* store_min, Output_* store_max,
bool skip_nan, Index_ subtract = 0) :
326 my_num(num), my_store_min(store_min), my_store_max(store_max), my_skip_nan(skip_nan), my_subtract(subtract) {}
334 void add(
const Value_* value,
const Index_* index, Index_ number) {
339 std::fill_n(my_store_min, my_num, internal::choose_minimum_placeholder<Value_>());
342 std::fill_n(my_store_max, my_num, internal::choose_maximum_placeholder<Value_>());
346 for (Index_ i = 0; i < number; ++i) {
348 auto idx = index[i] - my_subtract;
350 my_store_min[idx] = val;
353 my_store_max[idx] = val;
362 for (Index_ i = 0; i < number; ++i) {
364 auto idx = index[i] - my_subtract;
366 auto& current = my_store_min[idx];
372 auto& current = my_store_max[idx];
388 for (Index_ i = 0; i < my_num; ++i) {
389 if (my_count > my_nonzero[i]) {
391 auto& current = my_store_min[i];
397 auto& current = my_store_max[i];
406 std::fill_n(my_store_min, my_num, internal::choose_minimum_placeholder<Value_>());
409 std::fill_n(my_store_max, my_num, internal::choose_maximum_placeholder<Value_>());
416 Output_* my_store_min;
417 Output_* my_store_max;
421 std::vector<Index_> my_nonzero;
443template<
typename Value_,
typename Index_,
typename Output_>
445 auto dim = (row ? mat.
nrow() : mat.
ncol());
446 auto otherdim = (row ? mat.
ncol() : mat.
nrow());
449 bool store_min = min_out != NULL;
450 bool store_max = max_out != NULL;
461 for (Index_ x = 0; x < l; ++x) {
462 auto out = ext->fetch(vbuffer.data(), NULL);
482 for (Index_ x = 0; x < otherdim; ++x) {
483 auto out = ext->fetch(vbuffer.data(), ibuffer.data());
484 runner.
add(out.value, out.index, out.number);
489 local_min.transfer();
492 local_max.transfer();
502 for (Index_ x = 0; x < l; ++x) {
503 auto ptr = ext->fetch(buffer.data());
522 for (Index_ x = 0; x < otherdim; ++x) {
523 auto ptr = ext->fetch(buffer.data());
529 local_min.transfer();
532 local_max.transfer();
545template<
typename Value_,
typename Index_,
typename Output_>
547 apply(row, *p, min_out, max_out, ropt);
567template<
typename Output_ =
double,
typename Value_,
typename Index_>
571 apply(
false, mat, mins.data(), maxs.data(), ropt);
572 return std::make_pair(std::move(mins), std::move(maxs));
579template<
typename Output_ =
double,
typename Value_,
typename Index_>
584template<
typename Output_ =
double,
typename Value_,
typename Index_>
589template<
typename Output_ =
double,
typename Value_,
typename Index_>
611template<
typename Output_ =
double,
typename Value_,
typename Index_>
615 apply(
true, mat, mins.data(), maxs.data(), ropt);
616 return std::make_pair(std::move(mins), std::move(maxs));
623template<
typename Output_ =
double,
typename Value_,
typename Index_>
628template<
typename Output_ =
double,
typename Value_,
typename Index_>
633template<
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:93
Running minima/maxima from dense data.
Definition ranges.hpp:196
void add(const Value_ *ptr)
Definition ranges.hpp:215
void finish()
Definition ranges.hpp:279
RunningDense(Index_ num, Output_ *store_min, Output_ *store_max, bool skip_nan)
Definition ranges.hpp:208
Running minima/maxima from sparse data.
Definition ranges.hpp:310
void finish()
Definition ranges.hpp:386
void add(const Value_ *value, const Index_ *index, Index_ number)
Definition ranges.hpp:334
RunningSparse(Index_ num, Output_ *store_min, Output_ *store_max, bool skip_nan, Index_ subtract=0)
Definition ranges.hpp:325
std::pair< std::vector< Output_ >, std::vector< Output_ > > by_row(const tatami::Matrix< Value_, Index_ > &mat, const Options &ropt)
Definition ranges.hpp:612
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *min_out, Output_ *max_out, const Options &ropt)
Definition ranges.hpp:444
std::pair< std::vector< Output_ >, std::vector< Output_ > > by_column(const tatami::Matrix< Value_, Index_ > &mat, const Options &ropt)
Definition ranges.hpp:568
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, const Index_ tasks, const int threads)
void resize_container_to_Index_size(Container_ &container, const Index_ x, Args_ &&... args)
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_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.