diff --git a/CMakeLists.txt b/CMakeLists.txt index 78196d49..960b7252 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,7 @@ compiled_test(test/axis_variant_test.cpp) compiled_test(test/detail_test.cpp) compiled_test(test/histogram_dynamic_test.cpp) compiled_test(test/histogram_mixed_test.cpp) +compiled_test(test/histogram_operators_test.cpp) compiled_test(test/histogram_test.cpp) compiled_test(test/indexed_test.cpp) compiled_test(test/internal_accumulators_test.cpp) diff --git a/examples/guide_histogram_operators.cpp b/examples/guide_histogram_operators.cpp index 6d2d5d6c..b80d1937 100644 --- a/examples/guide_histogram_operators.cpp +++ b/examples/guide_histogram_operators.cpp @@ -24,23 +24,24 @@ int main() { auto h3 = h1; h3 += h2; // counts are: 1 1 - // adding multiple histograms at once is efficient and does not create - // superfluous temporaries since operator+ functions are overloaded to - // accept and return rvalue references where possible + // adding multiple histograms at once is likely to be optimized by the compiler so that + // superfluous temporaries avoided, but no guarantees are given; use this equivalent + // code when you want to make sure: h4 = h1; h4 += h2; h4 += h3; auto h4 = h1 + h2 + h3; // counts are: 2 2 assert(h4.at(0) == 2 && h4.at(1) == 2); - // multiply by number - h4 *= 2; // counts are: 4 4 + // multiply by number; h4 *= 2 is not allowed, because the result of a multiplication is + // not a histogram anymore, it has the type boost::histogram::grid<...>) + auto g4 = h4 * 2; // counts are: 4 4 - // divide by number - auto h5 = h4 / 4; // counts are: 1 1 + // divide by number; g4 /= 4 also works + auto g5 = g4 / 4; // counts are: 1 1 - assert(h5.at(0) == 1 && h5.at(1) == 1); - assert(h4 != h5 && h4 == 4 * h5); + assert(g5.at(0) == 1 && g5.at(1) == 1); + assert(g4 != g5 && g4 == 4 * g5); - // note special effect of multiplication on weighted_sum variance + // note special effect of multiplication on weighted_sum auto h = bh::make_histogram_with(std::vector>(), bh::axis::regular<>(2, -1, 1)); h(-0.5); @@ -49,14 +50,14 @@ int main() { assert(h.at(0).value() == 1 && h.at(1).value() == 0); auto h_sum = h + h; - auto h_mul = 2 * h; + auto g_mul = 2 * h; // equality operator checks variances, so following statement is false - assert(h_sum != h_mul); + assert(h_sum != g_mul); // variance is different when histograms are scaled - assert(h_sum.at(0).value() == 2 && h_mul.at(0).value() == 2); - assert(h_sum.at(0).variance() == 2 && h_mul.at(0).variance() == 4); + assert(h_sum.at(0).value() == 2 && g_mul.at(0).value() == 2); + assert(h_sum.at(0).variance() == 2 && g_mul.at(0).variance() == 4); } //] diff --git a/include/boost/histogram.hpp b/include/boost/histogram.hpp index 8b7f693f..fccfc0b9 100644 --- a/include/boost/histogram.hpp +++ b/include/boost/histogram.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/histogram/accumulators/mean.hpp b/include/boost/histogram/accumulators/mean.hpp index f811086d..540c19ae 100644 --- a/include/boost/histogram/accumulators/mean.hpp +++ b/include/boost/histogram/accumulators/mean.hpp @@ -7,8 +7,9 @@ #ifndef BOOST_HISTOGRAM_ACCUMULATORS_MEAN_HPP #define BOOST_HISTOGRAM_ACCUMULATORS_MEAN_HPP -#include +#include #include +#include namespace boost { namespace histogram { @@ -75,4 +76,12 @@ private: } // namespace histogram } // namespace boost +namespace std { +template +struct common_type, + boost::histogram::accumulators::mean> { + using type = boost::histogram::accumulators::mean>; +}; +} // namespace std + #endif diff --git a/include/boost/histogram/accumulators/ostream_operators.hpp b/include/boost/histogram/accumulators/ostream_operators.hpp index 899ebd8c..79982acd 100644 --- a/include/boost/histogram/accumulators/ostream_operators.hpp +++ b/include/boost/histogram/accumulators/ostream_operators.hpp @@ -7,7 +7,7 @@ #ifndef BOOST_HISTOGRAM_ACCUMULATORS_OSTREAM_OPERATORS_HPP #define BOOST_HISTOGRAM_ACCUMULATORS_OSTREAM_OPERATORS_HPP -#include +#include #include namespace boost { diff --git a/include/boost/histogram/accumulators/sum.hpp b/include/boost/histogram/accumulators/sum.hpp index 34ad4bb9..cc4fc71f 100644 --- a/include/boost/histogram/accumulators/sum.hpp +++ b/include/boost/histogram/accumulators/sum.hpp @@ -7,8 +7,9 @@ #ifndef BOOST_HISTOGRAM_ACCUMULATORS_SUM_HPP #define BOOST_HISTOGRAM_ACCUMULATORS_SUM_HPP -#include +#include #include +#include namespace boost { namespace histogram { @@ -84,4 +85,12 @@ private: } // namespace histogram } // namespace boost +namespace std { +template +struct common_type, + boost::histogram::accumulators::sum> { + using type = boost::histogram::accumulators::sum>; +}; +} // namespace std + #endif diff --git a/include/boost/histogram/accumulators/weighted_mean.hpp b/include/boost/histogram/accumulators/weighted_mean.hpp index 9bd8be3c..574058c8 100644 --- a/include/boost/histogram/accumulators/weighted_mean.hpp +++ b/include/boost/histogram/accumulators/weighted_mean.hpp @@ -7,7 +7,8 @@ #ifndef BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_MEAN_HPP #define BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_MEAN_HPP -#include +#include +#include namespace boost { namespace histogram { @@ -79,4 +80,12 @@ private: } // namespace histogram } // namespace boost +namespace std { +template +struct common_type, + boost::histogram::accumulators::weighted_mean> { + using type = boost::histogram::accumulators::weighted_mean>; +}; +} // namespace std + #endif diff --git a/include/boost/histogram/accumulators/weighted_sum.hpp b/include/boost/histogram/accumulators/weighted_sum.hpp index 33ff8632..4754fdc0 100644 --- a/include/boost/histogram/accumulators/weighted_sum.hpp +++ b/include/boost/histogram/accumulators/weighted_sum.hpp @@ -7,7 +7,8 @@ #ifndef BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_SUM_HPP #define BOOST_HISTOGRAM_ACCUMULATORS_WEIGHTED_SUM_HPP -#include +#include +#include namespace boost { namespace histogram { @@ -88,4 +89,11 @@ private: } // namespace histogram } // namespace boost +namespace std { +template +struct common_type, + boost::histogram::accumulators::weighted_sum> { + using type = boost::histogram::accumulators::weighted_sum>; +}; +} // namespace std #endif diff --git a/include/boost/histogram/adaptive_storage.hpp b/include/boost/histogram/adaptive_storage.hpp index ece20135..82bbbd1b 100644 --- a/include/boost/histogram/adaptive_storage.hpp +++ b/include/boost/histogram/adaptive_storage.hpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/boost/histogram/algorithm/project.hpp b/include/boost/histogram/algorithm/project.hpp index 005fb0ad..61ee3bb0 100644 --- a/include/boost/histogram/algorithm/project.hpp +++ b/include/boost/histogram/algorithm/project.hpp @@ -23,24 +23,24 @@ namespace histogram { namespace algorithm { /** - Returns a lower-dimensional histogram, summing over removed axes. + Returns a lower-dimensional grid, summing over removed axes. Arguments are the source histogram and compile-time numbers, the remaining indices of the axes. Returns a new histogram which only contains the subset of axes. The source histogram is summed over the removed axes. */ -template -auto project(const histogram& hist, std::integral_constant n, - Ns... ns) { +template