35 template<
typename Factor>
52 std::vector<std::vector<Factor> >
factors;
78 template<
typename Factor,
typename Combined>
80 std::vector<size_t> indices(n);
81 std::iota(indices.begin(), indices.end(), 0);
83 std::sort(indices.begin(), indices.end(), [&](
size_t left,
size_t right) ->
bool {
84 for (auto curf : factors) {
85 if (curf[left] < curf[right]) {
87 } else if (curf[left] > curf[right]) {
94 Combinations<Factor> output(factors.size());
99 combined[last] = counter;
100 output.counts.push_back(1);
101 for (
size_t f = 0; f < factors.size(); ++f) {
102 output.factors[f].push_back(factors[f][last]);
106 for (
size_t i = 1; i < n; ++i) {
107 auto current = indices[i];
109 for (
auto curf : factors) {
110 if (curf[last] < curf[current]) {
117 for (
size_t f = 0; f < factors.size(); ++f) {
118 output.factors[f].push_back(factors[f][current]);
120 output.counts.push_back(1);
123 ++(output.counts.back());
126 combined[current] = counter;
149 template<
typename Combined =
int,
typename Factor>
150 static std::pair<Combinations<Factor>, std::vector<Combined> >
combine_factors(
size_t n, std::vector<const Factor*> factors) {
157 template<
bool sparse_,
typename Index_,
typename Contents_,
typename Factor_,
typename Sum_,
typename Detected_>
158 void compute_row(Index_ i, Index_ nc,
const Contents_& row,
const Factor_* factor, std::vector<Sum_>& tmp_sums, std::vector<Sum_*>& sums, std::vector<Detected_>& tmp_detected, std::vector<Detected_*>& detected) {
160 std::fill(tmp_sums.begin(), tmp_sums.end(), 0);
162 if constexpr(sparse_) {
163 for (Index_ j = 0; j < row.number; ++j) {
164 tmp_sums[factor[row.index[j]]] += row.value[j];
167 for (Index_ j = 0; j < nc; ++j) {
168 tmp_sums[factor[j]] += row[j];
173 for (Index_ l = 0; l < tmp_sums.size(); ++l) {
174 sums[l][i] = tmp_sums[l];
178 if (detected.size()) {
179 std::fill(tmp_detected.begin(), tmp_detected.end(), 0);
181 if constexpr(sparse_) {
182 for (Index_ j = 0; j < row.number; ++j) {
183 tmp_detected[factor[row.index[j]]] += (row.value[j] > 0);
186 for (Index_ j = 0; j < nc; ++j) {
187 tmp_detected[factor[j]] += (row[j] > 0);
191 for (Index_ l = 0; l < tmp_detected.size(); ++l) {
192 detected[l][i] = tmp_detected[l];
197 template<
bool row_,
bool sparse_,
typename Data_,
typename Index_,
typename Factor_,
typename Sum_,
typename Detected_>
198 void compute(
const tatami::Matrix<Data_, Index_>* p,
const Factor_* factor, std::vector<Sum_*>& sums, std::vector<Detected_*>& detected) {
200 opt.sparse_ordered_index =
false;
203 tatami::parallelize([&](
size_t, Index_ s, Index_ l) {
204 auto ext = tatami::consecutive_extractor<row_, sparse_>(p, s, l, opt);
205 std::vector<Sum_> tmp_sums(sums.size());
206 std::vector<Detected_> tmp_detected(detected.size());
209 std::vector<Data_> vbuffer(NC);
210 typename std::conditional<sparse_, std::vector<Index_>, Index_>::type ibuffer(NC);
212 for (Index_ x = s, end = s + l; x < end; ++x) {
213 if constexpr(sparse_) {
214 compute_row<true>(x, NC, ext->fetch(x, vbuffer.data(), ibuffer.data()), factor, tmp_sums, sums, tmp_detected, detected);
216 compute_row<false>(x, NC, ext->fetch(x, vbuffer.data()), factor, tmp_sums, sums, tmp_detected, detected);
219 }, p->nrow(), num_threads);
222 tatami::parallelize([&](
size_t, Index_ s, Index_ l) {
224 auto ext = tatami::consecutive_extractor<row_, sparse_>(p, 0, NC, s, l, opt);
225 std::vector<Data_> vbuffer(l);
226 typename std::conditional<sparse_, std::vector<Index_>, Index_>::type ibuffer(l);
228 for (Index_ x = 0; x < NC; ++x) {
229 auto current = factor[x];
231 if constexpr(sparse_) {
232 auto col = ext->fetch(x, vbuffer.data(), ibuffer.data());
234 auto& cursum = sums[current];
235 for (Index_ i = 0; i < col.number; ++i) {
236 cursum[col.index[i]] += col.value[i];
240 if (detected.size()) {
241 auto& curdetected = detected[current];
242 for (Index_ i = 0; i < col.number; ++i) {
243 curdetected[col.index[i]] += (col.value[i] > 0);
248 auto col = ext->fetch(x, vbuffer.data());
251 auto cursum = sums[current] + s;
252 for (Index_ i = 0; i < l; ++i) {
257 if (detected.size()) {
258 auto curdetected = detected[current] + s;
259 for (Index_ i = 0; i < l; ++i) {
260 curdetected[i] += (col[i] > 0);
265 }, p->nrow(), num_threads);
292 template<
typename Data,
typename Index,
typename Factor,
typename Sum,
typename Detected>
293 void run(
const tatami::Matrix<Data, Index>*
input,
const Factor*
factor, std::vector<Sum*> sums, std::vector<Detected*> detected) {
294 if (
input->prefer_rows()) {
295 if (
input->sparse()) {
301 if (
input->sparse()) {
317 static constexpr bool compute_sums =
true;
322 static constexpr bool compute_detected =
true;
327 static constexpr int num_threads = 1;
348 compute_detected =
c;
362 bool compute_sums = Defaults::compute_sums;
363 bool compute_detected = Defaults::compute_detected;
364 int num_threads = Defaults::num_threads;
372 template <
typename Sum,
typename Detected>
381 std::vector<std::vector<Sum> >
sums;
410 template<
typename Sum =
double,
typename Detected =
int,
typename Data,
typename Index,
typename Factor>
418 std::vector<Detected*>
detptr;
428 if (compute_detected) {