tatami_stats
Matrix statistics for tatami
Loading...
Searching...
No Matches
quantiles.hpp
Go to the documentation of this file.
1#ifndef TATAMI_STATS_QUANTILES_HPP
2#define TATAMI_STATS_QUANTILES_HPP
3
4#include "utils.hpp"
5
6#include <cmath>
7#include <vector>
8#include <algorithm>
9#include <limits>
10#include <type_traits>
11
12#include "tatami/tatami.hpp"
13#include "sanisizer/sanisizer.hpp"
14#include "quickstats/quickstats.hpp"
15
22namespace tatami_stats {
23
28namespace quantiles {
29
33struct Options {
38 bool skip_nan = false;
39
44 int num_threads = 1;
45};
46
64template<typename Value_, typename Index_, typename Output_>
65void apply(bool row, const tatami::Matrix<Value_, Index_>& mat, const double quantile, Output_* output, const Options& qopt) {
66 auto dim = (row ? mat.nrow() : mat.ncol());
67 auto otherdim = (row ? mat.ncol() : mat.nrow());
68
69 if (otherdim == 0) {
70 // Prevent initalize() from constructing with a fixed instance with otherdim == 0.
71 std::fill_n(output, dim, std::numeric_limits<Output_>::quiet_NaN());
72 return;
73 }
74
75 auto initialize = [&](
76 std::optional<quickstats::SingleQuantileFixedNumber<Output_, Index_> >& fixed,
77 std::optional<quickstats::SingleQuantileVariableNumber<Output_, Index_> >& variable
78 ) -> void {
79 if (qopt.skip_nan) {
80 variable.emplace(otherdim, quantile);
81 } else {
82 fixed.emplace(otherdim, quantile);
83 }
84 };
85
86 if (mat.sparse()) {
88 opt.sparse_extract_index = false;
89 opt.sparse_ordered_index = false; // we'll be sorting by value anyway.
90
91 tatami::parallelize([&](int, Index_ s, Index_ l) -> void {
92 auto ext = tatami::consecutive_extractor<true>(mat, row, s, l, opt);
94 auto vbuffer = buffer.data();
95
96 std::optional<quickstats::SingleQuantileFixedNumber<Output_, Index_> > qcalcs_fixed;
97 std::optional<quickstats::SingleQuantileVariableNumber<Output_, Index_> > qcalcs_var;
98 initialize(qcalcs_fixed, qcalcs_var);
99
100 for (Index_ x = 0; x < l; ++x) {
101 auto range = ext->fetch(vbuffer, NULL);
102 tatami::copy_n(range.value, range.number, vbuffer);
103
104 ::tatami_stats::internal::nanable_ifelse<Value_>(
105 qopt.skip_nan,
106 [&]() -> void {
107 auto lost = shift_nans(vbuffer, range.number);
108 output[x + s] = (*qcalcs_var)(otherdim - lost, range.number - lost, vbuffer + lost);
109 },
110 [&]() -> void {
111 output[x + s] = (*qcalcs_fixed)(range.number, vbuffer);
112 }
113 );
114
115 }
116 }, dim, qopt.num_threads);
117
118 } else {
119 tatami::parallelize([&](int, Index_ s, Index_ l) -> void {
121 auto ext = tatami::consecutive_extractor<false>(mat, row, s, l);
122
123 std::optional<quickstats::SingleQuantileFixedNumber<Output_, Index_> > qcalcs_fixed;
124 std::optional<quickstats::SingleQuantileVariableNumber<Output_, Index_> > qcalcs_var;
125 initialize(qcalcs_fixed, qcalcs_var);
126
127 for (Index_ x = 0; x < l; ++x) {
128 auto bufptr = buffer.data();
129 auto raw = ext->fetch(bufptr);
130 tatami::copy_n(raw, otherdim, bufptr);
131
132 ::tatami_stats::internal::nanable_ifelse<Value_>(
133 qopt.skip_nan,
134 [&]() -> void {
135 auto lost = shift_nans(bufptr, otherdim);
136 output[x + s] = (*qcalcs_var)(otherdim - lost, bufptr + lost);
137 },
138 [&]() -> void {
139 output[x + s] = (*qcalcs_fixed)(bufptr);
140 }
141 );
142 }
143 }, dim, qopt.num_threads);
144 }
145}
146
162template<typename Output_ = double, typename Value_, typename Index_>
163std::vector<Output_> by_column(const tatami::Matrix<Value_, Index_>& mat, const double quantile, const Options& qopt) {
165 apply(false, mat, quantile, output.data(), qopt);
166 return output;
167}
168
184template<typename Output_ = double, typename Value_, typename Index_>
185std::vector<Output_> by_row(const tatami::Matrix<Value_, Index_>& mat, const double quantile, const Options& qopt) {
187 apply(true, mat, quantile, output.data(), qopt);
188 return output;
189}
190
191}
192
193}
194
195#endif
virtual Index_ ncol() const=0
virtual Index_ nrow() const=0
virtual std::unique_ptr< MyopicSparseExtractor< Value_, Index_ > > sparse(bool row, const Options &opt) const=0
void apply(bool row, const tatami::Matrix< Value_, Index_ > &mat, const double quantile, Output_ *output, const Options &qopt)
Definition quantiles.hpp:65
std::vector< Output_ > by_column(const tatami::Matrix< Value_, Index_ > &mat, const double quantile, const Options &qopt)
Definition quantiles.hpp:163
std::vector< Output_ > by_row(const tatami::Matrix< Value_, Index_ > &mat, const double quantile, const Options &qopt)
Definition quantiles.hpp:185
Functions to compute statistics from a tatami::Matrix.
Definition counts.hpp:18
int parallelize(Function_ fun, const Index_ tasks, const int workers)
Value_ * copy_n(const Value_ *const input, const Size_ n, Value_ *const output)
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
Quantile calculation options.
Definition quantiles.hpp:33
bool skip_nan
Definition quantiles.hpp:38
int num_threads
Definition quantiles.hpp:44
Utilities for computing matrix statistics.