1#ifndef TATAMI_STATS_RANGES_HPP
2#define TATAMI_STATS_RANGES_HPP
47template<
typename Value_>
48constexpr Value_ choose_minimum_placeholder() {
50 if constexpr(std::numeric_limits<Value_>::has_infinity) {
51 return std::numeric_limits<Value_>::infinity();
53 return std::numeric_limits<Value_>::max();
57template<
typename Value_>
58constexpr Value_ choose_maximum_placeholder() {
60 if constexpr(std::numeric_limits<Value_>::has_infinity) {
61 return -std::numeric_limits<Value_>::infinity();
63 return std::numeric_limits<Value_>::lowest();
88template<
typename Value_,
typename Index_>
89Value_
direct(
const Value_* ptr, Index_ num,
bool minimum,
bool skip_nan) {
90 return ::tatami_stats::internal::nanable_ifelse_with_value<Value_>(
95 auto current = internal::choose_minimum_placeholder<Value_>();
96 for (Index_ i = 0; i < num; ++i) {
104 auto current = internal::choose_maximum_placeholder<Value_>();
105 for (Index_ i = 0; i < num; ++i) {
118 return *std::min_element(ptr, ptr + num);
120 return *std::max_element(ptr, ptr + num);
124 return internal::choose_minimum_placeholder<Value_>();
126 return internal::choose_maximum_placeholder<Value_>();
151template<
typename Value_,
typename Index_>
152Value_
direct(
const Value_* value, Index_ num_nonzero, Index_ num_all,
bool minimum,
bool skip_nan) {
154 auto candidate =
direct(value, num_nonzero, minimum, skip_nan);
155 if (num_nonzero < num_all) {
168 }
else if (num_all) {
173 return internal::choose_minimum_placeholder<Value_>();
175 return internal::choose_maximum_placeholder<Value_>();
193template<
typename Output_,
typename Value_,
typename Index_>
206 RunningDense(Index_ num, Output_* store_min, Output_* store_max,
bool skip_nan) :
207 my_num(num), my_store_min(store_min), my_store_max(store_max), my_skip_nan(skip_nan) {}
213 void add(
const Value_* ptr) {
216 ::tatami_stats::internal::nanable_ifelse<Value_>(
221 for (Index_ i = 0; i < my_num; ++i) {
223 if (std::isnan(val)) {
224 my_store_min[i] = internal::choose_minimum_placeholder<Value_>();
226 my_store_min[i] = val;
231 for (Index_ i = 0; i < my_num; ++i) {
233 if (std::isnan(val)) {
234 my_store_max[i] = internal::choose_maximum_placeholder<Value_>();
236 my_store_max[i] = val;
244 std::copy_n(ptr, my_num, my_store_min);
247 std::copy_n(ptr, my_num, my_store_max);
254 for (Index_ i = 0; i < my_num; ++i) {
256 auto& current = my_store_min[i];
263 for (Index_ i = 0; i < my_num; ++i) {
265 auto& current = my_store_max[i];
280 std::fill_n(my_store_min, my_num, internal::choose_minimum_placeholder<Value_>());
283 std::fill_n(my_store_max, my_num, internal::choose_maximum_placeholder<Value_>());
291 Output_* my_store_min;
292 Output_* my_store_max;
306template<
typename Output_,
typename Value_,
typename Index_>
322 RunningSparse(Index_ num, Output_* store_min, Output_* store_max,
bool skip_nan, Index_ subtract = 0) :
323 my_num(num), my_store_min(store_min), my_store_max(store_max), my_skip_nan(skip_nan), my_subtract(subtract) {}
331 void add(
const Value_* value,
const Index_* index, Index_ number) {
333 my_nonzero.resize(my_num);
336 std::fill_n(my_store_min, my_num, internal::choose_minimum_placeholder<Value_>());
339 std::fill_n(my_store_max, my_num, internal::choose_maximum_placeholder<Value_>());
343 for (Index_ i = 0; i < number; ++i) {
345 auto idx = index[i] - my_subtract;
347 my_store_min[idx] = val;
350 my_store_max[idx] = val;
359 for (Index_ i = 0; i < number; ++i) {
361 auto idx = index[i] - my_subtract;
363 auto& current = my_store_min[idx];
369 auto& current = my_store_max[idx];
385 for (Index_ i = 0; i < my_num; ++i) {
386 if (my_count > my_nonzero[i]) {
388 auto& current = my_store_min[i];
394 auto& current = my_store_max[i];
403 std::fill_n(my_store_min, my_num, internal::choose_minimum_placeholder<Value_>());
406 std::fill_n(my_store_max, my_num, internal::choose_maximum_placeholder<Value_>());
413 Output_* my_store_min;
414 Output_* my_store_max;
418 std::vector<Index_> my_nonzero;
439template<
typename Value_,
typename Index_,
typename Output_>
441 auto dim = (row ? mat.
nrow() : mat.
ncol());
442 auto otherdim = (row ? mat.
ncol() : mat.
nrow());
445 bool store_min = min_out != NULL;
446 bool store_max = max_out != NULL;
456 std::vector<Value_> vbuffer(otherdim);
457 for (Index_ x = 0; x < l; ++x) {
458 auto out = ext->fetch(vbuffer.data(), NULL);
471 std::vector<Value_> vbuffer(l);
472 std::vector<Index_> ibuffer(l);
478 for (Index_ x = 0; x < otherdim; ++x) {
479 auto out = ext->fetch(vbuffer.data(), ibuffer.data());
480 runner.
add(out.value, out.index, out.number);
485 local_min.transfer();
488 local_max.transfer();
497 std::vector<Value_> buffer(otherdim);
498 for (Index_ x = 0; x < l; ++x) {
499 auto ptr = ext->fetch(buffer.data());
512 std::vector<Value_> buffer(l);
518 for (Index_ x = 0; x < otherdim; ++x) {
519 auto ptr = ext->fetch(buffer.data());
525 local_min.transfer();
528 local_max.transfer();
541template<
typename Value_,
typename Index_,
typename Output_>
543 apply(row, *p, min_out, max_out, ropt);
562template<
typename Output_ =
double,
typename Value_,
typename Index_>
564 std::vector<Output_> mins(mat.
ncol()), maxs(mat.
ncol());
565 apply(
false, mat, mins.data(), maxs.data(), ropt);
566 return std::make_pair(std::move(mins), std::move(maxs));
573template<
typename Output_ =
double,
typename Value_,
typename Index_>
578template<
typename Output_ =
double,
typename Value_,
typename Index_>
583template<
typename Output_ =
double,
typename Value_,
typename Index_>
604template<
typename Output_ =
double,
typename Value_,
typename Index_>
606 std::vector<Output_> mins(mat.
nrow()), maxs(mat.
nrow());
607 apply(
true, mat, mins.data(), maxs.data(), ropt);
608 return std::make_pair(std::move(mins), std::move(maxs));
615template<
typename Output_ =
double,
typename Value_,
typename Index_>
620template<
typename Output_ =
double,
typename Value_,
typename Index_>
625template<
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:79
Running minima/maxima from dense data.
Definition ranges.hpp:194
void add(const Value_ *ptr)
Definition ranges.hpp:213
void finish()
Definition ranges.hpp:277
RunningDense(Index_ num, Output_ *store_min, Output_ *store_max, bool skip_nan)
Definition ranges.hpp:206
Running minima/maxima from sparse data.
Definition ranges.hpp:307
void finish()
Definition ranges.hpp:383
void add(const Value_ *value, const Index_ *index, Index_ number)
Definition ranges.hpp:331
RunningSparse(Index_ num, Output_ *store_min, Output_ *store_max, bool skip_nan, Index_ subtract=0)
Definition ranges.hpp:322
std::pair< std::vector< Output_ >, std::vector< Output_ > > by_row(const tatami::Matrix< Value_, Index_ > &mat, const Options &ropt)
Definition ranges.hpp:605
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, Output_ *min_out, Output_ *max_out, const Options &ropt)
Definition ranges.hpp:440
std::pair< std::vector< Output_ >, std::vector< Output_ > > by_column(const tatami::Matrix< Value_, Index_ > &mat, const Options &ropt)
Definition ranges.hpp:563
Value_ direct(const Value_ *ptr, Index_ num, bool minimum, bool skip_nan)
Definition ranges.hpp:89
Functions to compute statistics from a tatami::Matrix.
Definition counts.hpp:18
void parallelize(Function_ fun, Index_ tasks, int threads)
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:28
bool skip_nan
Definition ranges.hpp:33
int num_threads
Definition ranges.hpp:39
Utilities for computing matrix statistics.