mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-11 13:14:06 +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;
|
++iaxis;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto storage = detail::make_default(unsafe_access::storage(hist));
|
auto idx = detail::make_stack_buffer<int>(axes);
|
||||||
auto result = Histogram(std::move(axes), std::move(storage));
|
auto irange = detail::make_stack_buffer<std::pair<int, int>>(axes);
|
||||||
|
detail::for_each_axis(axes, [it = irange.begin()](const auto& a) mutable {
|
||||||
auto idx = detail::make_stack_buffer<int>(unsafe_access::axes(result));
|
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)) {
|
for (auto&& x : indexed(hist, coverage::all)) {
|
||||||
auto i = idx.begin();
|
auto i = idx.begin();
|
||||||
auto o = opts.begin();
|
auto o = opts.begin();
|
||||||
|
auto ir = irange.begin();
|
||||||
|
bool valid = true;
|
||||||
|
|
||||||
for (auto j : x.indices()) {
|
for (auto j : x.indices()) {
|
||||||
*i = (j - o->begin);
|
*i = (j - o->begin);
|
||||||
if (*i <= -1)
|
if (*i <= -1) {
|
||||||
*i = -1;
|
*i = -1;
|
||||||
else {
|
if (*i < ir->first) valid = false;
|
||||||
|
} else {
|
||||||
*i /= o->merge;
|
*i /= o->merge;
|
||||||
const int end = (o->end - o->begin) / 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;
|
++i;
|
||||||
++o;
|
++o;
|
||||||
|
++ir;
|
||||||
}
|
}
|
||||||
result.at(idx) += *x;
|
|
||||||
|
if (valid) result.at(idx) += *x;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
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.001)).axis(), R(4, 2, -2));
|
||||||
BOOST_TEST_EQ(reduce(h, shrink(2, -1)).axis(), R(3, 2, -1));
|
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() {
|
int main() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user