From fd0b7dea8df5d883d18330503e22b0eb2df7c0ea Mon Sep 17 00:00:00 2001 From: Hans Dembinski Date: Tue, 22 Jan 2019 22:14:38 +0100 Subject: [PATCH] better reference docu --- include/boost/histogram/accumulators/sum.hpp | 49 ++++++++++------- .../histogram/accumulators/weighted_sum.hpp | 54 +++++++++---------- include/boost/histogram/axis/iterator.hpp | 7 +++ include/boost/histogram/axis/regular.hpp | 2 +- include/boost/histogram/axis/variant.hpp | 35 +++++++----- include/boost/histogram/histogram.hpp | 25 ++++++--- include/boost/histogram/serialization.hpp | 8 +-- test/internal_accumulators_test.cpp | 26 ++++----- test/storage_adaptor_test.cpp | 7 ++- 9 files changed, 121 insertions(+), 92 deletions(-) diff --git a/include/boost/histogram/accumulators/sum.hpp b/include/boost/histogram/accumulators/sum.hpp index 35ca767b..5b89b614 100644 --- a/include/boost/histogram/accumulators/sum.hpp +++ b/include/boost/histogram/accumulators/sum.hpp @@ -31,36 +31,41 @@ template class sum { public: sum() = default; - explicit sum(const RealType& value) noexcept : sum_(value), cor_(0) {} + + /// Initialize sum to value + explicit sum(const RealType& value) noexcept : large_(value) {} + + /// Set sum to value sum& operator=(const RealType& value) noexcept { - sum_ = value; - cor_ = 0; + large_ = value; + small_ = 0; return *this; } - void operator()() { operator+=(1); } + /// Increment sum by one + sum& operator++() { return operator+=(1); } - void operator()(const RealType& x) { operator+=(x); } - - sum& operator+=(const RealType& x) { - auto temp = sum_ + x; // prevent optimization - if (std::abs(sum_) >= std::abs(x)) - cor_ += (sum_ - temp) + x; + /// Increment sum by value + sum& operator+=(const RealType& value) { + auto temp = large_ + value; // prevent optimization + if (std::abs(large_) >= std::abs(value)) + small_ += (large_ - temp) + value; else - cor_ += (x - temp) + sum_; - sum_ = temp; + small_ += (value - temp) + large_; + large_ = temp; return *this; } - sum& operator*=(const RealType& x) { - sum_ *= x; - cor_ *= x; + /// Scale by value + sum& operator*=(const RealType& value) { + large_ *= value; + small_ *= value; return *this; } template bool operator==(const sum& rhs) const noexcept { - return sum_ == rhs.sum_ && cor_ == rhs.cor_; + return large_ == rhs.large_ && small_ == rhs.small_; } template @@ -68,17 +73,21 @@ public: return !operator==(rhs); } - const RealType& large() const noexcept { return sum_; } - const RealType& small() const noexcept { return cor_; } + /// Return large part of the sum. + const RealType& large() const { return large_; } + + /// Return small part of the sum. + const RealType& small() const { return small_; } // allow implicit conversion to RealType - operator RealType() const { return sum_ + cor_; } + operator RealType() const { return large_ + small_; } template void serialize(Archive&, unsigned /* version */); private: - RealType sum_ = 0, cor_ = 0; + RealType large_ = RealType(); + RealType small_ = RealType(); }; } // namespace accumulators diff --git a/include/boost/histogram/accumulators/weighted_sum.hpp b/include/boost/histogram/accumulators/weighted_sum.hpp index cc7fffee..81b3791f 100644 --- a/include/boost/histogram/accumulators/weighted_sum.hpp +++ b/include/boost/histogram/accumulators/weighted_sum.hpp @@ -19,49 +19,45 @@ template class weighted_sum { public: weighted_sum() = default; - explicit weighted_sum(const RealType& value) noexcept : sum_(value), sum2_(value) {} + explicit weighted_sum(const RealType& value) noexcept + : sum_of_weights_(value), sum_of_weights_squared_(value) {} weighted_sum(const RealType& value, const RealType& variance) noexcept - : sum_(value), sum2_(variance) {} + : sum_of_weights_(value), sum_of_weights_squared_(variance) {} - void operator()() { - sum_ += 1; - sum2_ += 1; - } + /// Increment by one. + weighted_sum& operator++() { return operator+=(1); } + /// Increment by value. template - void operator()(const T& w) { - sum_ += w; - sum2_ += w * w; - } - - // used when adding non-weighted histogram to weighted histogram - template - weighted_sum& operator+=(const T& x) { - sum_ += x; - sum2_ += x; + weighted_sum& operator+=(const T& value) { + sum_of_weights_ += value; + sum_of_weights_squared_ += value * value; return *this; } + /// Added another weighted sum. template weighted_sum& operator+=(const weighted_sum& rhs) { - sum_ += static_cast(rhs.sum_); - sum2_ += static_cast(rhs.sum2_); + sum_of_weights_ += static_cast(rhs.sum_of_weights_); + sum_of_weights_squared_ += static_cast(rhs.sum_of_weights_squared_); return *this; } + /// Scale by value. weighted_sum& operator*=(const RealType& x) { - sum_ *= x; - sum2_ *= x * x; + sum_of_weights_ *= x; + sum_of_weights_squared_ *= x * x; return *this; } bool operator==(const RealType& rhs) const noexcept { - return sum_ == rhs && sum2_ == rhs; + return sum_of_weights_ == rhs && sum_of_weights_squared_ == rhs; } template bool operator==(const weighted_sum& rhs) const noexcept { - return sum_ == rhs.sum_ && sum2_ == rhs.sum2_; + return sum_of_weights_ == rhs.sum_of_weights_ && + sum_of_weights_squared_ == rhs.sum_of_weights_squared_; } template @@ -69,20 +65,24 @@ public: return !operator==(rhs); } - const RealType& value() const noexcept { return sum_; } - const RealType& variance() const noexcept { return sum2_; } + /// Return value of the sum. + const RealType& value() const noexcept { return sum_of_weights_; } + + /// Return estimated variance of the sum. + const RealType& variance() const noexcept { return sum_of_weights_squared_; } // lossy conversion must be explicit - template + template explicit operator T() const { - return static_cast(sum_); + return static_cast(sum_of_weights_); } template void serialize(Archive&, unsigned /* version */); private: - RealType sum_ = RealType(), sum2_ = RealType(); + RealType sum_of_weights_ = RealType(); + RealType sum_of_weights_squared_ = RealType(); }; } // namespace accumulators diff --git a/include/boost/histogram/axis/iterator.hpp b/include/boost/histogram/axis/iterator.hpp index cf9c7ddc..590c818e 100644 --- a/include/boost/histogram/axis/iterator.hpp +++ b/include/boost/histogram/axis/iterator.hpp @@ -46,16 +46,23 @@ public: using const_iterator = iterator; using const_reverse_iterator = boost::reverse_iterator; + /// Bin iterator to beginning of the axis (read-only). const_iterator begin() const noexcept { return const_iterator(*static_cast(this), 0); } + + /// Bin iterator to the end of the axis (read-only). const_iterator end() const noexcept { return const_iterator(*static_cast(this), static_cast(this)->size()); } + + /// Reverse bin iterator to the last entry of the axis (read-only). const_reverse_iterator rbegin() const noexcept { return boost::make_reverse_iterator(end()); } + + /// Reverse bin iterator to the end (read-only). const_reverse_iterator rend() const noexcept { return boost::make_reverse_iterator(begin()); } diff --git a/include/boost/histogram/axis/regular.hpp b/include/boost/histogram/axis/regular.hpp index bfa8260b..eaeb737b 100644 --- a/include/boost/histogram/axis/regular.hpp +++ b/include/boost/histogram/axis/regular.hpp @@ -110,7 +110,7 @@ struct sqrt { /// Pow transform for equidistant bins in pow-space. struct pow { - double power = 1; + double power = 1; /**< power index */ explicit pow(double p) : power(p) {} pow() = default; diff --git a/include/boost/histogram/axis/variant.hpp b/include/boost/histogram/axis/variant.hpp index 21e0405c..d4fbd55a 100644 --- a/include/boost/histogram/axis/variant.hpp +++ b/include/boost/histogram/axis/variant.hpp @@ -162,11 +162,11 @@ public: return visit([&u](const auto& a) { return traits::index(a, u); }, *this); } - // Throws invalid_argument exception if axis has incompatible call signature - template - std::pair update(const U& u) { - return visit([&u](auto& a) { return traits::update(a, u); }, *this); - } + // // Throws invalid_argument exception if axis has incompatible call signature + // template + // std::pair update(const U& u) { + // return visit([&u](auto& a) { return traits::update(a, u); }, *this); + // } // Only works for axes with value method that returns something convertible to // double and will throw a runtime_error otherwise, see axis::traits::value @@ -212,9 +212,9 @@ public: template void serialize(Archive& ar, unsigned); - template - friend auto visit(Functor&&, Variant &&) - -> detail::visitor_return_type; + template + friend auto visit(Visitor&&, Variant &&) + -> detail::visitor_return_type; template friend T& get(variant& v); @@ -232,43 +232,52 @@ public: friend const T* get_if(const variant* v); }; -template -auto visit(Functor&& f, Variant&& v) -> detail::visitor_return_type { - using R = detail::visitor_return_type; +/// Apply visitor to variant +template +auto visit(Visitor&& vis, Variant&& var) + -> detail::visitor_return_type { + using R = detail::visitor_return_type; using B = detail::copy_qualifiers::base_type>; - return boost::apply_visitor(detail::functor_wrapper(f), static_cast(v)); + return boost::apply_visitor(detail::functor_wrapper(vis), + static_cast(var)); } +/// Return lvalue reference to T, throws unspecified exception if type does not match template T& get(variant& v) { using B = typename variant::base_type; return boost::get(static_cast(v)); } +/// Return rvalue reference to T, throws unspecified exception if type does not match template T&& get(variant&& v) { using B = typename variant::base_type; return boost::get(static_cast(v)); } +/// Return const reference to T, throws unspecified exception if type does not match template const T& get(const variant& v) { using B = typename variant::base_type; return boost::get(static_cast(v)); } +/// Returns pointer to T in variant or null pointer if type does not match template T* get_if(variant* v) { using B = typename variant::base_type; return boost::relaxed_get(static_cast(v)); } +/// Returns pointer to const T in variant or null pointer if type does not match template const T* get_if(const variant* v) { using B = typename variant::base_type; return boost::relaxed_get(static_cast(v)); } +#ifndef BOOST_HISTOGRAM_DOXYGEN_INVOKED // pass-through version for generic programming, if U is axis instead of variant template decltype(auto) get(U&& u) { @@ -287,6 +296,8 @@ const T* get_if(const U* u) { return std::is_same>::value ? reinterpret_cast(u) : nullptr; } +#endif + } // namespace axis } // namespace histogram } // namespace boost diff --git a/include/boost/histogram/histogram.hpp b/include/boost/histogram/histogram.hpp index 9a00cb10..07203346 100644 --- a/include/boost/histogram/histogram.hpp +++ b/include/boost/histogram/histogram.hpp @@ -81,8 +81,7 @@ public: } template - explicit histogram(A&& a, S&& s) - : axes_(std::forward(a)), storage_(std::forward(s)) { + histogram(A&& a, S&& s) : axes_(std::forward(a)), storage_(std::forward(s)) { storage_.reset(detail::bincount(axes_)); } @@ -125,34 +124,33 @@ public: not convertible to the value type accepted by the axis or passing the wrong number of arguments causes a throw of std::invalid_argument. - # Axis with multiple arguments + **Axis with multiple arguments** If the histogram contains an axis which accepts a std::tuple of arguments, the arguments for that axis need to passed as a std::tuple, for example, std::make_tuple(1.2, 2.3). If the histogram contains only this axis and no other, the arguments can be passed directly. - # Weights + **Weights** An optional weight can be passed as the first or last argument with the weight helper function. Compilation fails if the storage elements do not support weights. - # Samples + **Samples** If the storage elements accept samples, pass them with the sample helper function in addition to the axis arguments, which can be the first or last argument. The sample helper function can pass one or more arguments to the storage element. If samples and weights are used together, they can be passed in any order at the beginning or end of the argument list. */ - //@{ template auto operator()(const Ts&... ts) { return operator()(std::forward_as_tuple(ts...)); } + /// Fill histogram with values and optional weight or sample from a tuple. template auto operator()(const std::tuple& t) { return detail::fill(storage_, axes_, t); } - //@} /// Add values of another histogram. template @@ -190,7 +188,6 @@ public: decltype(auto) at(int t, Ts... ts) const { return at(std::forward_as_tuple(t, ts...)); } - //@} /// Access cell value at integral indices stored in std::tuple. /// @copydoc at(int t, Ts... ts) @@ -252,12 +249,24 @@ public: return !operator==(rhs); } + /// Return value iterator to the beginning of the histogram. iterator begin() noexcept { return storage_.begin(); } + + /// Return value iterator to the end in the histogram. iterator end() noexcept { return storage_.end(); } + /// Return value iterator to the beginning of the histogram (read-only). const_iterator begin() const noexcept { return storage_.begin(); } + + /// Return value iterator to the end in the histogram (read-only). const_iterator end() const noexcept { return storage_.end(); } + /// Return value iterator to the beginning of the histogram (read-only). + const_iterator cbegin() const noexcept { return storage_.begin(); } + + /// Return value iterator to the end in the histogram (read-only). + const_iterator cend() const noexcept { return storage_.end(); } + private: axes_type axes_; storage_type storage_; diff --git a/include/boost/histogram/serialization.hpp b/include/boost/histogram/serialization.hpp index 95a32485..47cb868c 100644 --- a/include/boost/histogram/serialization.hpp +++ b/include/boost/histogram/serialization.hpp @@ -81,15 +81,15 @@ namespace accumulators { template template void sum::serialize(Archive& ar, unsigned /* version */) { - ar& sum_; - ar& cor_; + ar& large_; + ar& small_; } template template void weighted_sum::serialize(Archive& ar, unsigned /* version */) { - ar& sum_; - ar& sum2_; + ar& sum_of_weights_; + ar& sum_of_weights_squared_; } template diff --git a/test/internal_accumulators_test.cpp b/test/internal_accumulators_test.cpp index 17b76ca2..5bc11b6a 100644 --- a/test/internal_accumulators_test.cpp +++ b/test/internal_accumulators_test.cpp @@ -31,7 +31,7 @@ int main() { BOOST_TEST_EQ(w, 1); BOOST_TEST_NE(w, 2); - w(2); + w += 2; BOOST_TEST_EQ(w.value(), 3); BOOST_TEST_EQ(w.variance(), 5); BOOST_TEST_EQ(w, w_t(3, 5)); @@ -44,20 +44,14 @@ int main() { // consistency: a weighted counter increased by weight 1 multiplied // by 2 must be the same as a weighted counter increased by weight 2 w_t u(0); - u(1); + ++u; u *= 2; BOOST_TEST_EQ(u, w_t(2, 4)); w_t v(0); - v(2); + v += 2; BOOST_TEST_EQ(u, v); - // consistency : a weight counter increased by a real number x - // is the same was adding x times weight(1) - w_t x(0); - x += 2; - BOOST_TEST_EQ(x, w_t(2, 2)); - // conversion to RealType w_t y(1, 2); BOOST_TEST_NE(y, 1); @@ -134,9 +128,9 @@ int main() { BOOST_TEST_EQ(bad_sum, 0); // instead of 2 accumulators::sum sum; - sum(); // equivalent to sum += 1 - sum(1e100); // equivalent to sum += 1e100 - sum += 1; + ++sum; + sum += 1e100; + ++sum; sum += -1e100; BOOST_TEST_EQ(sum, 2); } @@ -144,10 +138,10 @@ int main() { { accumulators::weighted_sum> w; - w(); - w(1e100); - w(); - w(-1e100); + ++w; + w += 1e100; + ++w; + w += -1e100; BOOST_TEST_EQ(w.value(), 2); BOOST_TEST_EQ(w.variance(), 2e200); diff --git a/test/storage_adaptor_test.cpp b/test/storage_adaptor_test.cpp index cabfc669..1ce0cd30 100644 --- a/test/storage_adaptor_test.cpp +++ b/test/storage_adaptor_test.cpp @@ -158,10 +158,9 @@ int main() { { auto a = storage_adaptor>>(); a.reset(1); - a[0](); - a[0](1); // rvalue weight - const auto weight = 2; - a[0](weight); // lvalue weight + ++a[0]; + a[0] += 1; + a[0] += 2; a[0] += accumulators::weighted_sum(1, 0); BOOST_TEST_EQ(a[0].value(), 5); BOOST_TEST_EQ(a[0].variance(), 6);