Skip to content

Commit e7e997b

Browse files
committed
Switched I to be a template type to avoid requiring a copy constructor.
1 parent 67ec04e commit e7e997b

11 files changed

Lines changed: 103 additions & 103 deletions

include/scran_markers/auc.hpp

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,21 @@ namespace internal {
1616
template<typename Value_, typename Group_, typename Output_>
1717
struct AucWorkspace {
1818
AucWorkspace(const std::size_t ngroups, Output_* const buffer) :
19-
less_than(sanisizer::cast<decltype(I(less_than.size()))>(ngroups)
19+
less_than(sanisizer::cast<I<decltype(less_than.size())> >(ngroups)
2020
#ifdef SCRAN_MARKERS_TEST_INIT
2121
, SCRAN_MARKERS_TEST_INIT
2222
#endif
2323
),
24-
equal(sanisizer::cast<decltype(I(equal.size()))>(ngroups)
24+
equal(sanisizer::cast<I<decltype(equal.size())> >(ngroups)
2525
#ifdef SCRAN_MARKERS_TEST_INIT
2626
, SCRAN_MARKERS_TEST_INIT
2727
#endif
2828
),
29-
outputs(sanisizer::cast<decltype(I(outputs.size()))>(ngroups)),
29+
outputs(sanisizer::cast<I<decltype(outputs.size())> >(ngroups)),
3030
output_start(buffer),
3131
output_end(buffer)
3232
{
33-
for (decltype(I(ngroups)) i = 0; i < ngroups; ++i) {
33+
for (I<decltype(ngroups)> i = 0; i < ngroups; ++i) {
3434
outputs[i] = output_end;
3535
output_end += ngroups;
3636
}
@@ -66,7 +66,7 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
6666
const auto ngroups = num_zeros.size();
6767

6868
const auto num_input = input.size();
69-
typedef decltype(I(num_input)) Position;
69+
typedef I<decltype(num_input)> Position;
7070

7171
auto inner_loop = [&](Position& pos) -> void {
7272
const auto& current = input[pos];
@@ -82,17 +82,17 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
8282
if (tied) {
8383
++equal[current.second]; // contribution of the current (tied) observation.
8484

85-
for (decltype(I(ngroups)) l = 1; l < ngroups; ++l) { // starting from 1 as zero has no work for the g < l condition anyway.
85+
for (I<decltype(ngroups)> l = 1; l < ngroups; ++l) { // starting from 1 as zero has no work for the g < l condition anyway.
8686
const auto num_eq = equal[l];
8787
if (num_eq) {
8888
const auto outptr = outputs[l];
89-
for (decltype(I(l)) g = 0; g < l; ++g) {
89+
for (I<decltype(l)> g = 0; g < l; ++g) {
9090
outptr[g] += num_eq * (less_than[g] + 0.5 * equal[g]);
9191
}
9292
}
9393
}
9494

95-
for (decltype(I(ngroups)) l = 0; l < ngroups; ++l) {
95+
for (I<decltype(ngroups)> l = 0; l < ngroups; ++l) {
9696
less_than[l] += equal[l];
9797
equal[l] = 0;
9898
}
@@ -113,17 +113,17 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
113113
}
114114

115115
// Values == 0.
116-
for (decltype(I(ngroups)) l = 1; l < ngroups; ++l) { // starting from 1, see above.
116+
for (I<decltype(ngroups)> l = 1; l < ngroups; ++l) { // starting from 1, see above.
117117
const auto num_z = num_zeros[l];
118118
if (num_z) {
119119
const auto outptr = outputs[l];
120-
for (decltype(I(l)) g = 0; g < l; ++g) {
120+
for (I<decltype(l)> g = 0; g < l; ++g) {
121121
outptr[g] += num_z * (less_than[g] + 0.5 * num_zeros[g]);
122122
}
123123
}
124124
}
125125

126-
for (decltype(I(ngroups)) l = 0; l < ngroups; ++l) {
126+
for (I<decltype(ngroups)> l = 0; l < ngroups; ++l) {
127127
less_than[l] += num_zeros[l];
128128
}
129129

@@ -134,8 +134,8 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
134134
}
135135

136136
// Filling in the other side.
137-
for (decltype(I(ngroups)) l = 1; l < ngroups; ++l) { // starting from 1, see above.
138-
for (decltype(I(l)) g = 0; g < l; ++g) {
137+
for (I<decltype(ngroups)> l = 1; l < ngroups; ++l) { // starting from 1, see above.
138+
for (I<decltype(l)> g = 0; g < l; ++g) {
139139
const Output_ prod = static_cast<Output_>(totals[l]) * static_cast<Output_>(totals[g]);
140140
outputs[g][l] = prod - outputs[l][g];
141141

@@ -163,7 +163,7 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
163163
const auto ngroups = num_zeros.size();
164164

165165
const auto num_input = input.size();
166-
typedef decltype(I(num_input)) Position;
166+
typedef I<decltype(num_input)> Position;
167167

168168
auto inner_loop = [&](Position& pos, Position& comp) -> void {
169169
const auto& current = input[pos];
@@ -186,20 +186,20 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
186186
if (tied) {
187187
do {
188188
const auto outptr = outputs[input[pos].second];
189-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
189+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
190190
outptr[g] += less_than[g] + 0.5 * equal[g];
191191
}
192192
++pos;
193193
} while (pos != num_input && input[pos].first == current.first);
194194

195-
for (decltype(I(ngroups)) l = 0; l < ngroups; ++l) {
195+
for (I<decltype(ngroups)> l = 0; l < ngroups; ++l) {
196196
less_than[l] += equal[l];
197197
equal[l] = 0;
198198
}
199199
} else {
200200
do {
201201
const auto outptr = outputs[input[pos].second];
202-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
202+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
203203
outptr[g] += less_than[g];
204204
}
205205
++pos;
@@ -244,11 +244,11 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
244244
++comp;
245245
}
246246

247-
for (decltype(I(ngroups)) l = 0; l < ngroups; ++l) {
247+
for (I<decltype(ngroups)> l = 0; l < ngroups; ++l) {
248248
const auto num_z = num_zeros[l];
249249
if (num_z) {
250250
const auto outptr = outputs[l];
251-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
251+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
252252
outptr[g] += less_than[g] * num_z;
253253
}
254254
}
@@ -263,29 +263,29 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
263263
}
264264

265265
if (tied) {
266-
for (decltype(I(ngroups)) l = 0; l < ngroups; ++l) {
266+
for (I<decltype(ngroups)> l = 0; l < ngroups; ++l) {
267267
const auto num_z = num_zeros[l];
268268
if (num_z) {
269269
const auto outptr = outputs[l];
270-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
270+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
271271
outptr[g] += 0.5 * equal[g] * num_z;
272272
}
273273
}
274274
}
275275

276-
for (decltype(I(ngroups)) l = 0; l < ngroups; ++l) {
276+
for (I<decltype(ngroups)> l = 0; l < ngroups; ++l) {
277277
less_than[l] += equal[l];
278278
equal[l] = 0;
279279
}
280280
}
281281

282282
// Or to each other, if the threshold is zero.
283283
if (threshold == 0) {
284-
for (decltype(I(ngroups)) l = 0; l < ngroups; ++l) {
284+
for (I<decltype(ngroups)> l = 0; l < ngroups; ++l) {
285285
const auto num_z = num_zeros[l];
286286
if (num_z) {
287287
const auto outptr = outputs[l];
288-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
288+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
289289
outptr[g] += num_z * 0.5 * num_zeros[g];
290290
}
291291
}
@@ -300,13 +300,13 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
300300
// Adding the contribution of zeros (in terms of the limit _being_ at zero + threshold)
301301
while (pos != num_input && static_cast<Threshold_>(input[pos].first) == threshold) {
302302
const auto outptr = outputs[input[pos].second];
303-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
303+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
304304
outptr[g] += less_than[g] + 0.5 * num_zeros[g];
305305
}
306306
++pos;
307307
}
308308

309-
for (decltype(I(ngroups)) l = 0; l < ngroups; ++l) {
309+
for (I<decltype(ngroups)> l = 0; l < ngroups; ++l) {
310310
less_than[l] += num_zeros[l];
311311
}
312312

@@ -316,8 +316,8 @@ void compute_pairwise_auc(AucWorkspace<Value_, Group_, Output_>& work, const std
316316

317317
// Dividing by the product of sizes.
318318
if (normalize) {
319-
for (decltype(I(ngroups)) l = 0; l < ngroups; ++l) {
320-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
319+
for (I<decltype(ngroups)> l = 0; l < ngroups; ++l) {
320+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
321321
const Output_ prod = static_cast<Output_>(totals[l]) * static_cast<Output_>(totals[g]);
322322
if (prod) {
323323
outputs[l][g] /= prod;

include/scran_markers/average_group_stats.hpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ namespace internal {
1616
template<typename Stat_>
1717
std::vector<Stat_> compute_total_weight_per_group(const std::size_t ngroups, const std::size_t nblocks, const Stat_* const combo_weights) {
1818
auto output = sanisizer::create<std::vector<Stat_> >(ngroups);
19-
for (decltype(I(nblocks)) b = 0; b < nblocks; ++b) {
20-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
19+
for (I<decltype(nblocks)> b = 0; b < nblocks; ++b) {
20+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
2121
output[g] += combo_weights[sanisizer::nd_offset<std::size_t>(g, ngroups, b)];
2222
}
2323
}
@@ -34,7 +34,7 @@ void average_group_stats_blockmean(
3434
const Stat_* const total_weights,
3535
const std::vector<Stat_*>& out_stats
3636
) {
37-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
37+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
3838
auto& output = out_stats[g][gene];
3939

4040
const auto total_weight = total_weights[g];
@@ -44,7 +44,7 @@ void average_group_stats_blockmean(
4444
}
4545

4646
Stat_ sum = 0;
47-
for (decltype(I(nblocks)) b = 0; b < nblocks; ++b) {
47+
for (I<decltype(nblocks)> b = 0; b < nblocks; ++b) {
4848
// Remember, blocks are the slower changing dimension, so we need to jump by 'ngroups'.
4949
const auto offset = sanisizer::nd_offset<std::size_t>(g, ngroups, b);
5050
const auto& curweight = combo_weights[offset];
@@ -67,10 +67,10 @@ void average_group_stats_blockquantile(
6767
scran_blocks::SingleQuantileVariable<Stat_, typename std::vector<Stat_>::iterator>& qcalc,
6868
const std::vector<Stat_*>& out_stats
6969
) {
70-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
70+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
7171
buffer.clear();
7272

73-
for (decltype(I(nblocks)) b = 0; b < nblocks; ++b) {
73+
for (I<decltype(nblocks)> b = 0; b < nblocks; ++b) {
7474
// Remember, blocks are the slower changing dimension, so we need to jump by 'ngroups'.
7575
const auto offset = sanisizer::nd_offset<std::size_t>(g, ngroups, b);
7676
const auto val = stats[offset];
@@ -92,9 +92,9 @@ void preallocate_average_results(
9292
) {
9393
res.reserve(ngroups);
9494
ptrs.reserve(ngroups);
95-
for (decltype(I(ngroups)) g = 0; g < ngroups; ++g) {
95+
for (I<decltype(ngroups)> g = 0; g < ngroups; ++g) {
9696
res.emplace_back(
97-
sanisizer::cast<decltype(I(res.front().size()))>(ngenes)
97+
sanisizer::cast<I<decltype(res.front().size())> >(ngenes)
9898
#ifdef SCRAN_MARKERS_TEST_INIT
9999
, SCRAN_MARKERS_TEST_INIT
100100
#endif

include/scran_markers/block_averages.hpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,20 @@ class PrecomputedPairwiseWeights {
3636
// 'combo_weights' are expected to be 'ngroups * nblocks' arrays where
3737
// groups are the faster-changing dimension and the blocks are slower.
3838
PrecomputedPairwiseWeights(const std::size_t ngroups, const std::size_t nblocks, const Stat_* const combo_weights) :
39-
my_total(sanisizer::product<decltype(I(my_total.size()))>(ngroups, ngroups)),
40-
my_by_block(sanisizer::product<decltype(I(my_by_block.size()))>(my_total.size(), nblocks)),
39+
my_total(sanisizer::product<I<decltype(my_total.size())> >(ngroups, ngroups)),
40+
my_by_block(sanisizer::product<I<decltype(my_by_block.size())> >(my_total.size(), nblocks)),
4141
my_ngroups(ngroups),
4242
my_nblocks(nblocks)
4343
{
4444
auto blocks_in_use = sanisizer::create<std::vector<std::size_t> >(my_total.size());
45-
for (decltype(I(nblocks)) b = 0; b < nblocks; ++b) {
46-
for (decltype(I(ngroups)) g1 = 1; g1 < ngroups; ++g1) {
45+
for (I<decltype(nblocks)> b = 0; b < nblocks; ++b) {
46+
for (I<decltype(ngroups)> g1 = 1; g1 < ngroups; ++g1) {
4747
const auto w1 = combo_weights[sanisizer::nd_offset<std::size_t>(g1, ngroups, b)];
4848
if (w1 == 0) {
4949
continue;
5050
}
5151

52-
for (decltype(I(g1)) g2 = 0; g2 < g1; ++g2) {
52+
for (I<decltype(g1)> g2 = 0; g2 < g1; ++g2) {
5353
const auto w2 = combo_weights[sanisizer::nd_offset<std::size_t>(g2, ngroups, b)];
5454
if (w2 == 0) {
5555
continue;
@@ -71,15 +71,15 @@ class PrecomputedPairwiseWeights {
7171
// So, we set the weight to 1 to ensure that the weighted mean calculation is a no-op,
7272
// i.e., there won't be any introduction of floating-point errors from a mult/div by the weight.
7373
// Zero weights do need to be preserved, though, as mult/div by zero gives NaN.
74-
for (decltype(I(ngroups)) g1 = 1; g1 < ngroups; ++g1) {
75-
for (decltype(I(g1)) g2 = 0; g2 < g1; ++g2) {
74+
for (I<decltype(ngroups)> g1 = 1; g1 < ngroups; ++g1) {
75+
for (I<decltype(g1)> g2 = 0; g2 < g1; ++g2) {
7676
const auto out_offset1 = sanisizer::nd_offset<std::size_t>(g2, ngroups, g1);
7777
if (blocks_in_use[out_offset1] != 1) {
7878
continue;
7979
}
8080

8181
my_total[out_offset1] = 1;
82-
for (decltype(I(nblocks)) b = 0; b < nblocks; ++b) {
82+
for (I<decltype(nblocks)> b = 0; b < nblocks; ++b) {
8383
auto& curweight = my_by_block[sanisizer::nd_offset<std::size_t>(b, nblocks, out_offset1)];
8484
curweight = (curweight > 0);
8585
my_by_block[sanisizer::nd_offset<std::size_t>(b, nblocks, g1, ngroups, g2)] = curweight;
@@ -88,8 +88,8 @@ class PrecomputedPairwiseWeights {
8888
}
8989

9090
// Filling the other side of my_totals, for completeness.
91-
for (decltype(I(ngroups)) g1 = 1; g1 < ngroups; ++g1) {
92-
for (decltype(I(g1)) g2 = 0; g2 < g1; ++g2) {
91+
for (I<decltype(ngroups)> g1 = 1; g1 < ngroups; ++g1) {
92+
for (I<decltype(g1)> g2 = 0; g2 < g1; ++g2) {
9393
my_total[sanisizer::nd_offset<std::size_t>(g1, ngroups, g2)] = my_total[sanisizer::nd_offset<std::size_t>(g2, ngroups, g1)];
9494
}
9595
}

include/scran_markers/cohens_d.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ std::pair<Stat_, Stat_> compute_cohens_d_blockmean(
7676

7777
std::pair<Stat_, Stat_> output(0, 0);
7878
Stat_ total_weight = 0; // need to calculate it dynamically, in case there are NaN variances for non-zero weights (e.g., one observation per block).
79-
for (decltype(I(nblocks)) b = 0; b < nblocks; ++b) {
79+
for (I<decltype(nblocks)> b = 0; b < nblocks; ++b) {
8080
const auto weight = winfo.first[b];
8181
if (weight == 0) {
8282
continue;
@@ -125,8 +125,8 @@ void compute_pairwise_cohens_d_blockmean(
125125
const PrecomputedPairwiseWeights<Stat_>& preweights,
126126
Stat_* const output)
127127
{
128-
for (decltype(I(ngroups)) g1 = 0; g1 < ngroups; ++g1) {
129-
for (decltype(I(g1)) g2 = 0; g2 < g1; ++g2) {
128+
for (I<decltype(ngroups)> g1 = 0; g1 < ngroups; ++g1) {
129+
for (I<decltype(g1)> g2 = 0; g2 < g1; ++g2) {
130130
const auto tmp = compute_cohens_d_blockmean(g1, g2, means, vars, ngroups, nblocks, threshold, preweights);
131131
output[sanisizer::nd_offset<std::size_t>(g2, ngroups, g1)] = tmp.first;
132132
output[sanisizer::nd_offset<std::size_t>(g1, ngroups, g2)] = tmp.second;
@@ -151,7 +151,7 @@ std::pair<Stat_, Stat_> compute_cohens_d_blockquantile(
151151
buffer.clear();
152152
rev_buffer.clear();
153153

154-
for (decltype(I(nblocks)) b = 0; b < nblocks; ++b) {
154+
for (I<decltype(nblocks)> b = 0; b < nblocks; ++b) {
155155
const auto offset1 = sanisizer::nd_offset<std::size_t>(g1, ngroups, b); // remember, 'groups' is the faster-changing dimension.
156156
const auto offset2 = sanisizer::nd_offset<std::size_t>(g2, ngroups, b);
157157
const auto left_var = vars[offset1];
@@ -200,8 +200,8 @@ void compute_pairwise_cohens_d_blockquantile(
200200
scran_blocks::SingleQuantileVariable<Stat_, typename std::vector<Stat_>::iterator>& qcalc,
201201
Stat_* const output
202202
) {
203-
for (decltype(I(ngroups)) g1 = 0; g1 < ngroups; ++g1) {
204-
for (decltype(I(g1)) g2 = 0; g2 < g1; ++g2) {
203+
for (I<decltype(ngroups)> g1 = 0; g1 < ngroups; ++g1) {
204+
for (I<decltype(g1)> g2 = 0; g2 < g1; ++g2) {
205205
const auto tmp = compute_cohens_d_blockquantile(g1, g2, means, vars, ngroups, nblocks, threshold, buffer, rev_buffer, qcalc);
206206
output[sanisizer::nd_offset<std::size_t>(g2, ngroups, g1)] = tmp.first;
207207
output[sanisizer::nd_offset<std::size_t>(g1, ngroups, g2)] = tmp.second;

include/scran_markers/create_combinations.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace internal {
2020
template<typename Group_, typename Block_>
2121
std::vector<std::size_t> create_combinations(const std::size_t ngroups, const Group_* const group, const Block_* const block, const std::size_t NC) {
2222
auto combinations = sanisizer::create<std::vector<std::size_t> >(NC);
23-
for (decltype(I(NC)) c = 0; c < NC; ++c) {
23+
for (I<decltype(NC)> c = 0; c < NC; ++c) {
2424
combinations[c] = sanisizer::nd_offset<std::size_t>(group[c], ngroups, block[c]); // group is the faster changing dimension.
2525
}
2626
return combinations;

0 commit comments

Comments
 (0)