• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 Hans Dembinski
2 //
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt
5 // or copy at http://www.boost.org/LICENSE_1_0.txt)
6 
7 #ifndef BOOST_HISTOGRAM_ALGORITHM_SUM_HPP
8 #define BOOST_HISTOGRAM_ALGORITHM_SUM_HPP
9 
10 #include <boost/histogram/accumulators/sum.hpp>
11 #include <boost/histogram/fwd.hpp>
12 #include <boost/histogram/indexed.hpp>
13 #include <boost/mp11/utility.hpp>
14 #include <type_traits>
15 
16 namespace boost {
17 namespace histogram {
18 namespace algorithm {
19 
20 /** Compute the sum over all histogram cells (underflow/overflow included by default).
21 
22   The implementation favors accuracy and protection against overflow over speed. If the
23   value type of the histogram is an integral or floating point type,
24   accumulators::sum<double> is used to compute the sum, else the original value type is
25   used. Compilation fails, if the value type does not support operator+=. The return type
26   is double if the value type of the histogram is integral or floating point, and the
27   original value type otherwise.
28 
29   If you need a different trade-off, you can write your own loop or use `std::accumulate`:
30   ```
31   // iterate over all bins
32   auto sum_all = std::accumulate(hist.begin(), hist.end(), 0.0);
33 
34   // skip underflow/overflow bins
35   double sum = 0;
36   for (auto&& x : indexed(hist))
37     sum += *x; // dereference accessor
38 
39   // or:
40   // auto ind = boost::histogram::indexed(hist);
41   // auto sum = std::accumulate(ind.begin(), ind.end(), 0.0);
42   ```
43 
44   @returns accumulator type or double
45 
46   @param hist Const reference to the histogram.
47   @param cov  Iterate over all or only inner bins (optional, default: all).
48 */
49 template <class A, class S>
sum(const histogram<A,S> & hist,const coverage cov=coverage::all)50 auto sum(const histogram<A, S>& hist, const coverage cov = coverage::all) {
51   using T = typename histogram<A, S>::value_type;
52   using sum_type = mp11::mp_if<std::is_arithmetic<T>, accumulators::sum<double>, T>;
53   sum_type sum;
54   if (cov == coverage::all)
55     for (auto&& x : hist) sum += x;
56   else
57     // sum += x also works if sum_type::operator+=(const sum_type&) exists
58     for (auto&& x : indexed(hist)) sum += *x;
59   using R = mp11::mp_if<std::is_arithmetic<T>, double, T>;
60   return static_cast<R>(sum);
61 }
62 
63 } // namespace algorithm
64 } // namespace histogram
65 } // namespace boost
66 
67 #endif
68