From ca3fd5d3a94d2785a9bf23b18bf4cbbfbed1bb81 Mon Sep 17 00:00:00 2001 From: Hans Dembinski Date: Wed, 29 Mar 2017 21:15:57 +0200 Subject: [PATCH] missing files --- .../histogram/histogram_impl_dynamic.hpp | 321 ++++++++++++++++++ .../boost/histogram/histogram_impl_static.hpp | 235 +++++++++++++ 2 files changed, 556 insertions(+) create mode 100644 include/boost/histogram/histogram_impl_dynamic.hpp create mode 100644 include/boost/histogram/histogram_impl_static.hpp diff --git a/include/boost/histogram/histogram_impl_dynamic.hpp b/include/boost/histogram/histogram_impl_dynamic.hpp new file mode 100644 index 00000000..28f2d672 --- /dev/null +++ b/include/boost/histogram/histogram_impl_dynamic.hpp @@ -0,0 +1,321 @@ +// Copyright 2015-2016 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_HISTOGRAM_DYNAMIC_IMPL_HPP_ +#define _BOOST_HISTOGRAM_HISTOGRAM_DYNAMIC_IMPL_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace histogram { + +template +class histogram { + static_assert(!mpl::empty::value, "at least one axis required"); + using size_pair = std::pair; + +public: + using axis_type = typename make_variant_over::type; + using value_type = typename Storage::value_type; + +private: + using axes_type = std::vector; + +public: + histogram() = default; + + template + explicit histogram(const Axes1 &... axes) : axes_({axis_type(axes)...}) { + storage_ = Storage(field_count()); + } + + template > + histogram(Iterator axes_begin, Iterator axes_end) + : axes_(std::distance(axes_begin, axes_end)) { + std::copy(axes_begin, axes_end, axes_.begin()); + storage_ = Storage(field_count()); + } + + template + explicit histogram(const histogram &rhs) + : axes_(rhs.axes_.begin(), rhs.axes_.end()), storage_(rhs.storage_) {} + + template + explicit histogram(histogram &&rhs) + : axes_(std::move(rhs.axes_)), storage_(std::move(rhs.storage_)) {} + + template + histogram &operator=(const histogram &rhs) { + if (static_cast(this) != static_cast(&rhs)) { + axes_ = rhs.axes_; + storage_ = rhs.storage_; + } + return *this; + } + + template + histogram &operator=(histogram &&rhs) { + if (static_cast(this) != static_cast(&rhs)) { + axes_ = std::move(rhs.axes_); + storage_ = std::move(rhs.storage_); + } + return *this; + } + + template + bool operator==(const histogram &rhs) const { + if (mpl::empty::type>::value) { + return false; + } + if (dim() != rhs.dim()) { + return false; + } + if (!axes_equal_to(rhs.axes_)) { + return false; + } + if (!(storage_ == rhs.storage_)) { + return false; + } + return true; + } + + template + bool operator!=(const histogram &rhs) const { + return !operator==(rhs); + } + + template + histogram &operator+=(const histogram &rhs) { + static_assert( + !mpl::empty::type>::value, + "histograms lack common axes types"); + if (dim() != rhs.dim()) { + throw std::logic_error("dimensions of histograms differ"); + } + if (size() != rhs.size()) { + throw std::logic_error("sizes of histograms differ"); + } + if (!axes_equal_to(rhs.axes_)) { + throw std::logic_error("axes of histograms differ"); + } + storage_ += rhs.storage_; + return *this; + } + + template void fill(Values... values) { + BOOST_ASSERT_MSG(sizeof...(values) == dim(), + "number of arguments does not match histogram dimension"); + const auto p = + apply_lin(size_pair(0, 1), values...); + if (p.second) { + storage_.increase(p.first); + } + } + + template > + void fill(Iterator begin, Iterator end) { + BOOST_ASSERT_MSG(std::distance(begin, end) == dim(), + "number of arguments does not match histogram dimension"); + const auto p = apply_lin_iter(size_pair(0, 1), begin); + if (p.second) { + storage_.increase(p.first); + } + } + + template void wfill(value_type w, Values... values) { + BOOST_ASSERT_MSG(sizeof...(values) == dim(), + "number of arguments does not match histogram dimension"); + const auto p = + apply_lin(size_pair(0, 1), values...); + if (p.second) { + storage_.increase(p.first, w); + } + } + + template > + void wfill(value_type w, Iterator begin, Iterator end) { + BOOST_ASSERT_MSG(std::distance(begin, end) == dim(), + "number of arguments does not match histogram dimension"); + const auto p = apply_lin_iter(size_pair(0, 1), begin); + if (p.second) { + storage_.increase(p.first, w); + } + } + + template value_type value(Indices... indices) const { + BOOST_ASSERT_MSG(sizeof...(indices) == dim(), + "number of arguments does not match histogram dimension"); + const auto p = + apply_lin(size_pair(0, 1), indices...); + if (p.second == 0) { + throw std::out_of_range("invalid index"); + } + return storage_.value(p.first); + } + + template > + value_type value(Iterator begin, Iterator end) const { + BOOST_ASSERT_MSG(std::distance(begin, end) == dim(), + "number of arguments does not match histogram dimension"); + const auto p = apply_lin_iter(size_pair(0, 1), begin); + if (p.second == 0) { + throw std::out_of_range("invalid index"); + } + return storage_.value(p.first); + } + + template value_type variance(Indices... indices) const { + static_assert(detail::has_variance::value, + "Storage lacks variance support"); + BOOST_ASSERT_MSG(sizeof...(indices) == dim(), + "number of arguments does not match histogram dimension"); + const auto p = + apply_lin(size_pair(0, 1), indices...); + if (p.second == 0) { + throw std::out_of_range("invalid index"); + } + return storage_.variance(p.first); + } + + template > + value_type variance(Iterator begin, Iterator end) const { + static_assert(detail::has_variance::value, + "Storage lacks variance support"); + BOOST_ASSERT_MSG(std::distance(begin, end) == dim(), + "number of arguments does not match histogram dimension"); + const auto p = apply_lin_iter(size_pair(0, 1), begin); + if (p.second == 0) { + throw std::out_of_range("invalid index"); + } + return storage_.variance(p.first); + } + + /// Number of axes (dimensions) of histogram + unsigned dim() const { return axes_.size(); } + + /// Total number of bins in the histogram (including underflow/overflow) + std::size_t size() const { return storage_.size(); } + + /// Sum of all counts in the histogram + double sum() const { + double result = 0.0; + for (std::size_t i = 0, n = size(); i < n; ++i) { + result += storage_.value(i); + } + return result; + } + + /// Return axis \a i + const axis_type &axis(unsigned i = 0) const { + BOOST_ASSERT_MSG(i < dim(), "axis index out of range"); + return axes_[i]; + } + + /// Return axis \a i (added for conformity with static_histogram interface) + template const axis_type &axis() const { + BOOST_ASSERT_MSG(N < dim(), "axis index out of range"); + return axes_[N]; + } + + /// Apply unary functor/function to each axis + template void for_each_axis(Unary &unary) const { + for (const auto &a : axes_) { + apply_visitor(detail::unary_visitor(unary), a); + } + } + +private: + axes_type axes_; + Storage storage_; + + std::size_t field_count() const { + detail::field_count fc; + for (const auto &a : axes_) { + apply_visitor(fc, a); + } + return fc.value; + } + + template bool axes_equal_to(const A &rhs) const { + detail::cmp_axis ca; + for (unsigned i = 0; i < dim(); ++i) { + if (!apply_visitor(ca, axes_[i], rhs[i])) { + return false; + } + } + return true; + } + + template