added sum algorithm

This commit is contained in:
Hans Dembinski 2018-11-13 15:12:00 +01:00
parent 04acab427d
commit 4bc30a74f0
7 changed files with 98 additions and 29 deletions

View File

@ -77,6 +77,7 @@ endfunction()
compiled_test(test/adaptive_storage_test.cpp)
compiled_test(test/algorithm_project_test.cpp)
compiled_test(test/algorithm_sum_test.cpp)
compiled_test(test/axis_regular_test.cpp)
compiled_test(test/axis_circular_test.cpp)
compiled_test(test/axis_variable_test.cpp)

View File

@ -0,0 +1,27 @@
// Copyright 2018 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_HISTOGRAM_ALGORITHM_SUM_HPP
#define BOOST_HISTOGRAM_ALGORITHM_SUM_HPP
#include <boost/histogram/histogram_fwd.hpp>
#include <numeric>
#include <type_traits>
namespace boost {
namespace histogram {
namespace algorithm {
template <typename A, typename S>
typename histogram<A, S>::value_type sum(const histogram<A, S>& h) {
using T = typename histogram<A, S>::value_type;
return std::accumulate(h.begin(), h.end(),
std::conditional_t<std::is_integral<T>::value, double, T>());
}
} // namespace algorithm
} // namespace histogram
} // namespace boost
#endif

View File

@ -227,28 +227,25 @@ using is_sample = is_sample_impl<unqual<T>>;
template <typename T, typename = decltype(*std::declval<T&>(), ++std::declval<T&>())>
struct requires_iterator {};
template <typename T, typename = mp11::mp_if<is_iterable<T>, void>>
template <typename T, typename = mp11::mp_if<is_iterable<unqual<T>>, void>>
struct requires_iterable {};
template <typename T, typename = mp11::mp_if<is_tuple<T>, void>>
template <typename T, typename = mp11::mp_if<is_tuple<unqual<T>>, void>>
struct requires_tuple {};
template <typename T, typename = mp11::mp_if<is_axis<T>, void>>
template <typename T, typename = mp11::mp_if<is_axis<unqual<T>>, void>>
struct requires_axis {};
template <typename T, typename = mp11::mp_if<is_axis_or_axis_variant<T>, void>>
template <typename T, typename = mp11::mp_if<is_axis_or_axis_variant<unqual<T>>, void>>
struct requires_axis_or_axis_variant {};
template <typename T, typename = mp11::mp_if<is_axis_vector<T>, void>>
template <typename T, typename = mp11::mp_if<is_axis_vector<unqual<T>>, void>>
struct requires_axis_vector {};
template <typename T, typename U, typename = mp11::mp_if<std::is_same<T, U>, void>>
struct requires_same {};
template <typename T, typename = mp11::mp_if<is_transform<T>, void>>
template <typename T, typename = mp11::mp_if<is_transform<unqual<T>>, void>>
struct requires_transform {};
template <typename T, typename = mp11::mp_if<is_storage<T>, void>>
template <typename T, typename = mp11::mp_if<is_storage<unqual<T>>, void>>
struct requires_storage {};
} // namespace detail

View File

@ -6,6 +6,7 @@
#include <boost/core/lightweight_test.hpp>
#include <boost/histogram/algorithm/project.hpp>
#include <boost/histogram/algorithm/sum.hpp>
#include <boost/histogram/axis/integer.hpp>
#include <boost/histogram/axis/ostream_operators.hpp>
#include <boost/histogram/literals.hpp>
@ -14,7 +15,7 @@
using namespace boost::histogram;
using namespace boost::histogram::literals; // to get _c suffix
using boost::histogram::algorithm::project;
using namespace boost::histogram::algorithm;
template <typename Tag>
void run_tests() {

View File

@ -0,0 +1,46 @@
// Copyright 2018 Hans Dembinski
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/core/lightweight_test.hpp>
#include <boost/histogram.hpp>
#include <boost/histogram/algorithm/sum.hpp>
#include "utility_histogram.hpp"
using namespace boost::histogram;
using namespace boost::histogram::literals; // to get _c suffix
using boost::histogram::algorithm::sum;
template <typename Tag>
void run_tests() {
auto ax = axis::integer<>(0, 100);
auto h1 = make(Tag(), ax);
for (unsigned i = 0; i < 100; ++i) h1(i);
BOOST_TEST_EQ(sum(h1), 100);
auto h2 = make_s(Tag(), std::vector<double>(), ax, ax);
for (unsigned i = 0; i < 100; ++i)
for (unsigned j = 0; j < 100; ++j) h2(i, j);
BOOST_TEST_EQ(sum(h2), 100000);
auto h3 = make_s(Tag(), std::array<int, 102>(), ax);
for (unsigned i = 0; i < 100; ++i) h3(i);
BOOST_TEST_EQ(sum(h3), 100);
auto h4 = make_s(Tag(), std::unordered_map<std::size_t, int>(), ax);
for (unsigned i = 0; i < 100; ++i) h3(i);
BOOST_TEST_EQ(sum(h3), 100);
}
int main() {
run_tests<static_tag>();
run_tests<dynamic_tag>();
return boost::report_errors();
}

View File

@ -9,6 +9,7 @@
#include <boost/histogram/accumulators/ostream_operators.hpp>
#include <boost/histogram/accumulators/weight.hpp>
#include <boost/histogram/adaptive_storage.hpp>
#include <boost/histogram/algorithm/sum.hpp>
#include <boost/histogram/axis/variant.hpp>
#include <boost/histogram/histogram.hpp>
#include <boost/histogram/literals.hpp>
@ -133,12 +134,12 @@ void run_tests() {
h(0, 0);
const auto href = h;
decltype(h) h2(std::move(h));
BOOST_TEST_EQ(sum(h), 0);
BOOST_TEST_EQ(algorithm::sum(h), 0);
BOOST_TEST_EQ(h.size(), 0);
BOOST_TEST_EQ(h2, href);
decltype(h) h3;
h3 = std::move(h2);
BOOST_TEST_EQ(sum(h2), 0);
BOOST_TEST_EQ(algorithm::sum(h2), 0);
BOOST_TEST_EQ(h2.size(), 0);
BOOST_TEST_EQ(h3, href);
}
@ -224,7 +225,7 @@ void run_tests() {
BOOST_TEST_EQ(h.rank(), 1);
BOOST_TEST_EQ(h.axis().size(), 2);
BOOST_TEST_EQ(sum(h), 4);
BOOST_TEST_EQ(algorithm::sum(h), 4);
BOOST_TEST_EQ(h.at(-1), 1);
BOOST_TEST_EQ(h.at(0), 2);
@ -242,7 +243,7 @@ void run_tests() {
BOOST_TEST_EQ(h.rank(), 1);
BOOST_TEST_EQ(h.axis().size(), 2);
BOOST_TEST_EQ(sum(h), 2);
BOOST_TEST_EQ(algorithm::sum(h), 2);
BOOST_TEST_EQ(h.at(0), 2);
BOOST_TEST_EQ(h.at(1), 0);
@ -258,7 +259,7 @@ void run_tests() {
BOOST_TEST_EQ(h.rank(), 1);
BOOST_TEST_EQ(h.axis().size(), 2);
BOOST_TEST_EQ(sum(h), 4);
BOOST_TEST_EQ(algorithm::sum(h), 4);
BOOST_TEST_EQ(h.at(0), 1);
BOOST_TEST_EQ(h.at(1), 1);
@ -274,8 +275,8 @@ void run_tests() {
h(1);
h(weight(2), 2);
BOOST_TEST_EQ(sum(h).value(), 5.5);
BOOST_TEST_EQ(sum(h).variance(), 7.25);
BOOST_TEST_EQ(algorithm::sum(h).value(), 5.5);
BOOST_TEST_EQ(algorithm::sum(h).variance(), 7.25);
BOOST_TEST_EQ(h[-1].value(), 1);
BOOST_TEST_EQ(h[-1].variance(), 1);
@ -321,7 +322,7 @@ void run_tests() {
BOOST_TEST_EQ(h.rank(), 2);
BOOST_TEST_EQ(h.axis(0_c).size(), 2);
BOOST_TEST_EQ(h.axis(1_c).size(), 3);
BOOST_TEST_EQ(sum(h), 3);
BOOST_TEST_EQ(algorithm::sum(h), 3);
BOOST_TEST_EQ(h.at(-1, 0), 0);
BOOST_TEST_EQ(h.at(-1, 1), 1);
@ -350,8 +351,8 @@ void run_tests() {
h(weight(5), -1, -10); // is ignored
h(weight(7), -10, 0); // -> -1, 1
BOOST_TEST_EQ(sum(h).value(), 18);
BOOST_TEST_EQ(sum(h).variance(), 150);
BOOST_TEST_EQ(algorithm::sum(h).value(), 18);
BOOST_TEST_EQ(algorithm::sum(h).variance(), 150);
BOOST_TEST_EQ(h.at(-1, 0).value(), 0);
BOOST_TEST_EQ(h.at(-1, 1).value(), 7);
@ -498,7 +499,7 @@ void run_tests() {
BOOST_TEST_EQ(h.at(0), 1);
BOOST_TEST_EQ(h.at(1), 1);
BOOST_TEST_EQ(h.at(2), 1);
BOOST_TEST_EQ(sum(h), 3);
BOOST_TEST_EQ(algorithm::sum(h), 3);
auto a = std::vector<double>();
std::partial_sum(h.begin(), h.end(), std::back_inserter(a));
@ -562,11 +563,11 @@ void run_tests() {
h(1);
BOOST_TEST_EQ(h.at(0), 1);
BOOST_TEST_EQ(h.at(1), 1);
BOOST_TEST_EQ(sum(h), 2);
BOOST_TEST_EQ(algorithm::sum(h), 2);
h.reset();
BOOST_TEST_EQ(h.at(0), 0);
BOOST_TEST_EQ(h.at(1), 0);
BOOST_TEST_EQ(sum(h), 0);
BOOST_TEST_EQ(algorithm::sum(h), 0);
}
// custom axes
@ -696,7 +697,7 @@ void run_tests() {
++it;
BOOST_TEST(it == h.end());
auto v = sum(h);
auto v = algorithm::sum(h);
BOOST_TEST_EQ(v.value(), 4);
BOOST_TEST_EQ(v.variance(), 6);
}

View File

@ -17,10 +17,6 @@
namespace boost {
namespace histogram {
template <typename Histogram>
auto sum(const Histogram& h) {
return std::accumulate(h.begin(), h.end(), typename Histogram::value_type(0));
}
template <typename... Ts>
auto make_axis_vector(Ts&&... ts) {