52template <
typename Sum_,
typename Detected_>
81template <
typename Sum_,
typename Detected_>
90 std::vector<std::vector<Sum_> >
sums;
105template<
bool sparse_,
typename Data_,
typename Index_,
typename Group_,
typename Sum_,
typename Detected_>
106void aggregate_across_cells_by_row(
108 const Group_*
const group,
117 const auto nsums = buffers.
sums.size();
118 auto tmp_sums = sanisizer::create<std::vector<Sum_> >(nsums);
119 const auto ndetected = buffers.
detected.size();
120 auto tmp_detected = sanisizer::create<std::vector<Detected_> >(ndetected);
122 const auto NC = p.
ncol();
125 if constexpr(sparse_) {
132 for (Index_ x = s, end = s + l; x < end; ++x) {
133 const auto row = [&]{
134 if constexpr(sparse_) {
135 return ext->fetch(vbuffer.data(), ibuffer.data());
137 return ext->fetch(vbuffer.data());
142 std::fill(tmp_sums.begin(), tmp_sums.end(), 0);
144 if constexpr(sparse_) {
145 for (Index_ j = 0; j < row.number; ++j) {
146 tmp_sums[group[row.index[j]]] += row.value[j];
149 for (Index_ j = 0; j < NC; ++j) {
150 tmp_sums[group[j]] += row[j];
155 for (I<
decltype(nsums)> l = 0; l < nsums; ++l) {
156 buffers.
sums[l][x] = tmp_sums[l];
161 std::fill(tmp_detected.begin(), tmp_detected.end(), 0);
163 if constexpr(sparse_) {
164 for (Index_ j = 0; j < row.number; ++j) {
165 tmp_detected[group[row.index[j]]] += (row.value[j] > 0);
168 for (Index_ j = 0; j < NC; ++j) {
169 tmp_detected[group[j]] += (row[j] > 0);
173 for (I<
decltype(ndetected)> l = 0; l < ndetected; ++l) {
174 buffers.
detected[l][x] = tmp_detected[l];
181template<
bool sparse_,
typename Data_,
typename Index_,
typename Group_,
typename Sum_,
typename Detected_>
182void aggregate_across_cells_by_column(
184 const Group_*
const group,
185 const AggregateAcrossCellsBuffers<Sum_, Detected_>& buffers,
186 const AggregateAcrossCellsOptions& options)
192 const auto NC = p.
ncol();
196 if constexpr(sparse_) {
203 const auto num_sums = buffers.sums.size();
204 auto get_sum = [&](Index_ i) -> Sum_* {
return buffers.sums[i]; };
205 tatami_stats::LocalOutputBuffers<Sum_, I<
decltype(get_sum)>> local_sums(t, num_sums, start, length, std::move(get_sum));
207 const auto num_detected = buffers.detected.size();
208 auto get_detected = [&](Index_ i) -> Detected_* {
return buffers.detected[i]; };
209 tatami_stats::LocalOutputBuffers<Detected_, I<
decltype(get_detected)>> local_detected(t, num_detected, start, length, std::move(get_detected));
211 for (Index_ x = 0; x < NC; ++x) {
212 const auto current = group[x];
214 if constexpr(sparse_) {
215 const auto col = ext->fetch(vbuffer.data(), ibuffer.data());
217 const auto cursum = local_sums.data(current);
218 for (Index_ i = 0; i < col.number; ++i) {
219 cursum[col.index[i] - start] += col.value[i];
223 const auto curdetected = local_detected.data(current);
224 for (Index_ i = 0; i < col.number; ++i) {
225 curdetected[col.index[i] - start] += (col.value[i] > 0);
230 const auto col = ext->fetch(vbuffer.data());
232 const auto cursum = local_sums.data(current);
233 for (Index_ i = 0; i < length; ++i) {
238 const auto curdetected = local_detected.data(current);
239 for (Index_ i = 0; i < length; ++i) {
240 curdetected[i] += (col[i] > 0);
246 local_sums.transfer();
247 local_detected.transfer();
248 }, p.
nrow(), options.num_threads);
274template<
typename Data_,
typename Index_,
typename Group_,
typename Sum_,
typename Detected_>
277 const Group_*
const group,
283 aggregate_across_cells_by_row<true>(input, group, buffers, options);
285 aggregate_across_cells_by_row<false>(input, group, buffers, options);
289 aggregate_across_cells_by_column<true>(input, group, buffers, options);
291 aggregate_across_cells_by_column<false>(input, group, buffers, options);
315template<
typename Sum_ =
double,
typename Detected_ =
int,
typename Data_,
typename Index_,
typename Group_>
318 const Group_*
const group,
321 const Index_ NR = input.
nrow();
322 const Index_ NC = input.
ncol();
323 const std::size_t ngroups = [&]{
325 return sanisizer::sum<std::size_t>(*std::max_element(group, group + NC), 1);
327 return static_cast<std::size_t
>(0);
335 sanisizer::resize(output.
sums, ngroups);
336 sanisizer::resize(buffers.
sums, ngroups);
337 for (I<
decltype(ngroups)> l = 0; l < ngroups; ++l) {
338 auto& cursum = output.
sums[l];
340#ifdef SCRAN_AGGREGATE_TEST_INIT
341 , SCRAN_AGGREGATE_TEST_INIT
344 buffers.
sums[l] = cursum.data();
349 sanisizer::resize(output.
detected, ngroups);
350 sanisizer::resize(buffers.
detected, ngroups);
351 for (I<
decltype(ngroups)> l = 0; l < ngroups; ++l) {
354#ifdef SCRAN_AGGREGATE_TEST_INIT
355 , SCRAN_AGGREGATE_TEST_INIT
358 buffers.
detected[l] = curdet.data();
void aggregate_across_cells(const tatami::Matrix< Data_, Index_ > &input, const Group_ *const group, const AggregateAcrossCellsBuffers< Sum_, Detected_ > &buffers, const AggregateAcrossCellsOptions &options)
Definition aggregate_across_cells.hpp:275