mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-09 23:04:07 +00:00
fix of reduce when histogram lacks flow bins
reducing histograms with axes that lacked flow bins failed before this patch
This commit is contained in:
parent
1540c4e94a
commit
81cf62d010
@ -263,26 +263,44 @@ decltype(auto) reduce(const Histogram& hist, const Iterable& options) {
|
||||
++iaxis;
|
||||
});
|
||||
|
||||
auto storage = detail::make_default(unsafe_access::storage(hist));
|
||||
auto result = Histogram(std::move(axes), std::move(storage));
|
||||
|
||||
auto idx = detail::make_stack_buffer<int>(unsafe_access::axes(result));
|
||||
auto idx = detail::make_stack_buffer<int>(axes);
|
||||
auto irange = detail::make_stack_buffer<std::pair<int, int>>(axes);
|
||||
detail::for_each_axis(axes, [it = irange.begin()](const auto& a) mutable {
|
||||
using A = std::decay_t<decltype(a)>;
|
||||
it->first = axis::traits::static_options<A>::test(axis::option::underflow) ? -1 : 0;
|
||||
it->second = axis::traits::static_options<A>::test(axis::option::overflow)
|
||||
? a.size() + 1
|
||||
: a.size();
|
||||
++it;
|
||||
});
|
||||
auto result =
|
||||
Histogram(std::move(axes), detail::make_default(unsafe_access::storage(hist)));
|
||||
for (auto&& x : indexed(hist, coverage::all)) {
|
||||
auto i = idx.begin();
|
||||
auto o = opts.begin();
|
||||
auto ir = irange.begin();
|
||||
bool valid = true;
|
||||
|
||||
for (auto j : x.indices()) {
|
||||
*i = (j - o->begin);
|
||||
if (*i <= -1)
|
||||
if (*i <= -1) {
|
||||
*i = -1;
|
||||
else {
|
||||
if (*i < ir->first) valid = false;
|
||||
} else {
|
||||
*i /= o->merge;
|
||||
const int end = (o->end - o->begin) / o->merge;
|
||||
if (*i > end) *i = end;
|
||||
if (*i >= end) {
|
||||
*i = end;
|
||||
if (*i >= ir->second) valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
++i;
|
||||
++o;
|
||||
++ir;
|
||||
}
|
||||
result.at(idx) += *x;
|
||||
|
||||
if (valid) result.at(idx) += *x;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -224,6 +224,43 @@ void run_tests() {
|
||||
BOOST_TEST_EQ(reduce(h, shrink(2, -1.001)).axis(), R(4, 2, -2));
|
||||
BOOST_TEST_EQ(reduce(h, shrink(2, -1)).axis(), R(3, 2, -1));
|
||||
}
|
||||
|
||||
// reduce on histogram with axis without flow bins, see GitHub issue #257
|
||||
{
|
||||
auto h = make(Tag(), axis::integer<int, use_default, axis::option::underflow_t>(0, 3),
|
||||
axis::integer<int, use_default, axis::option::overflow_t>(0, 3));
|
||||
|
||||
std::fill(h.begin(), h.end(), 1);
|
||||
|
||||
/*
|
||||
Original histogram:
|
||||
x
|
||||
-1 0 1 2
|
||||
-------------
|
||||
0| 1 1 1 1
|
||||
x 1| 1 1 1 1
|
||||
2| 1 1 1 1
|
||||
3| 1 1 1 1
|
||||
|
||||
Shrunk histogram:
|
||||
-1 0
|
||||
-------
|
||||
0| 2 1
|
||||
1| 4 2
|
||||
*/
|
||||
|
||||
auto hr = reduce(h, slice(0, 1, 2), slice(1, 1, 2));
|
||||
BOOST_TEST_EQ(hr.size(), 2 * 2);
|
||||
BOOST_TEST_EQ(hr.axis(0).size(), 1);
|
||||
BOOST_TEST_EQ(hr.axis(1).size(), 1);
|
||||
BOOST_TEST_EQ(hr.axis(0).bin(0), 1);
|
||||
BOOST_TEST_EQ(hr.axis(1).bin(0), 1);
|
||||
|
||||
BOOST_TEST_EQ(hr.at(-1, 0), 2);
|
||||
BOOST_TEST_EQ(hr.at(0, 0), 1);
|
||||
BOOST_TEST_EQ(hr.at(-1, 1), 4);
|
||||
BOOST_TEST_EQ(hr.at(0, 1), 2);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user