prepare/change interface for point-wise adding

This commit is contained in:
Hans Dembinski 2017-05-05 00:13:44 +02:00
parent cc45928cc8
commit 9606c38a64
8 changed files with 148 additions and 108 deletions

View File

@ -45,13 +45,13 @@ A `storage_type` is required to:
* have the following methods: * have the following methods:
* `std::size_t size() const` * `std::size_t size() const`
* `void increase(std::size_t index)` * `void increase(std::size_t index)`
* `void increase(std::size_t index, value_type n)`
* `value_type value(std::size_t index) const` * `value_type value(std::size_t index) const`
* `storage_type& operator+=(const storage_type& rhs)`
To support weighted fills, two additional methods are required: To support weighted fills, two additional methods are required:
* `value_type variance(std::size_t index) const` * `value_type variance(std::size_t index) const`
* `void increase(std::size_t index, value_type weight)` * `void weighted_increase(std::size_t index, value_type weight)`
[classref boost::histogram::container_storage] is a simple example of a storage type which does not support weighted fills. [classref boost::histogram::container_storage] is a simple example of a storage type which does not support weighted fills.

View File

@ -23,11 +23,18 @@ class weight {
public: public:
explicit weight(double v) : value(v) {} explicit weight(double v) : value(v) {}
explicit operator double() const { return value; } explicit operator double() const { return value; }
private: private:
double value; double value;
}; };
class count {
public:
explicit count(unsigned v) : value(v) {}
explicit operator unsigned() const { return value; }
private:
unsigned value;
};
} // namespace histogram } // namespace histogram
} // namespace boost } // namespace boost

View File

@ -15,7 +15,7 @@
#include <boost/histogram/detail/meta.hpp> #include <boost/histogram/detail/meta.hpp>
#include <boost/histogram/detail/utility.hpp> #include <boost/histogram/detail/utility.hpp>
#include <boost/histogram/histogram_fwd.hpp> #include <boost/histogram/histogram_fwd.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/int.hpp>
#include <boost/mpl/count.hpp> #include <boost/mpl/count.hpp>
#include <boost/mpl/empty.hpp> #include <boost/mpl/empty.hpp>
#include <boost/mpl/vector.hpp> #include <boost/mpl/vector.hpp>
@ -121,17 +121,19 @@ public:
if (!detail::axes_equal(axes_, rhs.axes_)) { if (!detail::axes_equal(axes_, rhs.axes_)) {
throw std::logic_error("axes of histograms differ"); throw std::logic_error("axes of histograms differ");
} }
storage_ += rhs.storage_; for (std::size_t i = 0, n = storage_.size(); i < n; ++i)
storage_.increase(i, rhs.storage_.value(i));
return *this; return *this;
} }
template <typename... Args> void fill(Args... args) noexcept { template <typename... Args> void fill(Args... args) noexcept {
using n_count = typename mpl::count<mpl::vector<Args...>, count>;
using n_weight = typename mpl::count<mpl::vector<Args...>, weight>; using n_weight = typename mpl::count<mpl::vector<Args...>, weight>;
static_assert(n_weight::value <= 1, static_assert((n_count::value + n_weight::value) <= 1,
"arguments may contain at most one instance of type weight"); "arguments may contain at most one instance of type count or weight");
BOOST_ASSERT_MSG(sizeof...(args) == dim() + n_weight::value, BOOST_ASSERT_MSG(sizeof...(args) == (dim() + n_count::value + n_weight::value),
"number of arguments does not match histogram dimension"); "number of arguments does not match histogram dimension");
fill_impl(mpl::bool_<(n_weight::value > 0)>(), args...); fill_impl(mpl::int_<(n_count::value + 2 * n_weight::value)>(), args...);
} }
template <typename Iterator, typename = detail::is_iterator<Iterator>> template <typename Iterator, typename = detail::is_iterator<Iterator>>
@ -152,7 +154,7 @@ public:
std::size_t idx = 0, stride = 1; std::size_t idx = 0, stride = 1;
apply_lin_iter<detail::xlin>(idx, stride, begin); apply_lin_iter<detail::xlin>(idx, stride, begin);
if (stride) { if (stride) {
storage_.increase(idx, static_cast<double>(w)); storage_.weighted_increase(idx, static_cast<double>(w));
} }
} }
@ -250,17 +252,7 @@ private:
} }
template <typename... Args> template <typename... Args>
inline void fill_impl(mpl::true_, const Args &... args) { inline void fill_impl(mpl::int_<0>, const Args &... args) {
std::size_t idx = 0, stride = 1;
double w = 0.0;
apply_lin_w<detail::xlin, 0, Args...>(idx, stride, w, args...);
if (stride) {
storage_.increase(idx, w);
}
}
template <typename... Args>
inline void fill_impl(mpl::false_, const Args &... args) {
std::size_t idx = 0, stride = 1; std::size_t idx = 0, stride = 1;
apply_lin<detail::xlin, 0, Args...>(idx, stride, args...); apply_lin<detail::xlin, 0, Args...>(idx, stride, args...);
if (stride) { if (stride) {
@ -268,6 +260,26 @@ private:
} }
} }
template <typename... Args>
inline void fill_impl(mpl::int_<1>, const Args &... args) {
std::size_t idx = 0, stride = 1;
unsigned n = 0;
apply_lin_x<detail::xlin, 0, unsigned, Args...>(idx, stride, n, args...);
if (stride) {
storage_.increase(idx, n);
}
}
template <typename... Args>
inline void fill_impl(mpl::int_<2>, const Args &... args) {
std::size_t idx = 0, stride = 1;
double w = 0.0;
apply_lin_x<detail::xlin, 0, double, Args...>(idx, stride, w, args...);
if (stride) {
storage_.weighted_increase(idx, w);
}
}
template <template <class, class> class Lin, typename Value> template <template <class, class> class Lin, typename Value>
struct lin_visitor : public static_visitor<void> { struct lin_visitor : public static_visitor<void> {
std::size_t &idx; std::size_t &idx;
@ -280,6 +292,9 @@ private:
} }
}; };
template <template <class, class> class Lin, unsigned D>
inline void apply_lin(std::size_t &, std::size_t &) const {}
template <template <class, class> class Lin, unsigned D, typename First, template <template <class, class> class Lin, unsigned D, typename First,
typename... Rest> typename... Rest>
inline void apply_lin(std::size_t &idx, std::size_t &stride, const First &x, inline void apply_lin(std::size_t &idx, std::size_t &stride, const First &x,
@ -288,29 +303,33 @@ private:
return apply_lin<Lin, D + 1, Rest...>(idx, stride, rest...); return apply_lin<Lin, D + 1, Rest...>(idx, stride, rest...);
} }
template <template <class, class> class Lin, unsigned D> template <template <class, class> class Lin, unsigned D, typename X>
inline void apply_lin(std::size_t &idx, std::size_t &stride) const {} inline void apply_lin_x(std::size_t &, std::size_t &, X &) const {}
template <template <class, class> class Lin, unsigned D, typename First, template <template <class, class> class Lin, unsigned D, typename X, typename First,
typename... Rest> typename... Rest>
inline typename std::enable_if<!(std::is_same<First, weight>::value)>::type inline typename std::enable_if<!(std::is_same<First, weight>::value || std::is_same<First, count>::value)>::type
apply_lin_w(std::size_t &idx, std::size_t &stride, double &w, const First &x, apply_lin_x(std::size_t &idx, std::size_t &stride, X &x, const First &first,
const Rest &... rest) const { const Rest &... rest) const {
apply_visitor(lin_visitor<Lin, First>(idx, stride, x), axes_[D]); apply_visitor(lin_visitor<Lin, First>(idx, stride, first), axes_[D]);
return apply_lin_w<Lin, D + 1, Rest...>(idx, stride, w, rest...); return apply_lin_x<Lin, D + 1, X, Rest...>(idx, stride, x, rest...);
} }
template <template <class, class> class Lin, unsigned D, typename, template <template <class, class> class Lin, unsigned D, typename X, typename,
typename... Rest> typename... Rest>
inline void apply_lin_w(std::size_t &idx, std::size_t &stride, double &w, inline void apply_lin_x(std::size_t &idx, std::size_t &stride, X &x,
const weight &x, const Rest &... rest) const { const weight &first, const Rest &... rest) const {
w = static_cast<double>(x); x = static_cast<X>(first);
return apply_lin_w<Lin, D, Rest...>(idx, stride, w, rest...); return apply_lin_x<Lin, D, X, Rest...>(idx, stride, x, rest...);
} }
template <template <class, class> class Lin, unsigned D> template <template <class, class> class Lin, unsigned D, typename X, typename,
inline void apply_lin_w(std::size_t &idx, std::size_t &stride, typename... Rest>
double &w) const {} inline void apply_lin_x(std::size_t &idx, std::size_t &stride, X &x,
const count &first, const Rest &... rest) const {
x = static_cast<X>(first);
return apply_lin_x<Lin, D, X, Rest...>(idx, stride, x, rest...);
}
template <template <class, class> class Lin, typename Iterator> template <template <class, class> class Lin, typename Iterator>
void apply_lin_iter(std::size_t &idx, std::size_t &stride, void apply_lin_iter(std::size_t &idx, std::size_t &stride,
@ -322,7 +341,8 @@ private:
} }
template <typename D, typename A, typename S> friend class histogram; template <typename D, typename A, typename S> friend class histogram;
template <typename K>
friend histogram reduce(const histogram&, const K&);
friend class ::boost::python::access; friend class ::boost::python::access;
friend class ::boost::serialization::access; friend class ::boost::serialization::access;
template <typename Archive> void serialize(Archive &, unsigned); template <typename Archive> void serialize(Archive &, unsigned);

View File

@ -26,7 +26,7 @@
#include <boost/histogram/detail/meta.hpp> #include <boost/histogram/detail/meta.hpp>
#include <boost/histogram/detail/utility.hpp> #include <boost/histogram/detail/utility.hpp>
#include <boost/histogram/histogram_fwd.hpp> #include <boost/histogram/histogram_fwd.hpp>
#include <boost/mpl/bool.hpp> #include <boost/mpl/int.hpp>
#include <boost/mpl/count.hpp> #include <boost/mpl/count.hpp>
#include <boost/mpl/empty.hpp> #include <boost/mpl/empty.hpp>
#include <boost/mpl/vector.hpp> #include <boost/mpl/vector.hpp>
@ -98,17 +98,19 @@ public:
if (!detail::axes_equal(axes_, rhs.axes_)) { if (!detail::axes_equal(axes_, rhs.axes_)) {
throw std::logic_error("axes of histograms differ"); throw std::logic_error("axes of histograms differ");
} }
storage_ += rhs.storage_; for (std::size_t i = 0, n = storage_.size(); i < n; ++i)
storage_.increase(i, rhs.storage_.value(i));
return *this; return *this;
} }
template <typename... Args> void fill(const Args &... args) { template <typename... Args> void fill(const Args &... args) {
using n_count = typename mpl::count<mpl::vector<Args...>, count>;
using n_weight = typename mpl::count<mpl::vector<Args...>, weight>; using n_weight = typename mpl::count<mpl::vector<Args...>, weight>;
static_assert(n_weight::value <= 1, static_assert((n_count::value + n_weight::value) <= 1,
"arguments may contain at most one instance of type weight"); "arguments may contain at most one instance of type count or weight");
static_assert(sizeof...(args) == axes_size::value + n_weight::value, static_assert(sizeof...(args) == (axes_size::value + n_count::value + n_weight::value),
"number of arguments does not match histogram dimension"); "number of arguments does not match histogram dimension");
fill_impl(mpl::bool_<(n_weight::value > 0)>(), args...); fill_impl(mpl::int_<(n_count::value + 2 * n_weight::value)>(), args...);
} }
template <typename... Indices> template <typename... Indices>
@ -187,7 +189,7 @@ private:
} }
template <typename... Args> template <typename... Args>
inline void fill_impl(mpl::false_, const Args &... args) { inline void fill_impl(mpl::int_<0>, const Args &... args) {
std::size_t idx = 0, stride = 1; std::size_t idx = 0, stride = 1;
apply_lin<detail::xlin, 0, Args...>(idx, stride, args...); apply_lin<detail::xlin, 0, Args...>(idx, stride, args...);
if (stride) { if (stride) {
@ -196,15 +198,28 @@ private:
} }
template <typename... Args> template <typename... Args>
inline void fill_impl(mpl::true_, const Args &... args) { inline void fill_impl(mpl::int_<1>, const Args &... args) {
std::size_t idx = 0, stride = 1; std::size_t idx = 0, stride = 1;
double w = 0.0; unsigned n = 0;
apply_lin_w<detail::xlin, 0, Args...>(idx, stride, w, args...); apply_lin_x<detail::xlin, 0, unsigned, Args...>(idx, stride, n, args...);
if (stride) { if (stride) {
storage_.increase(idx, w); storage_.increase(idx, n);
} }
} }
template <typename... Args>
inline void fill_impl(mpl::int_<2>, const Args &... args) {
std::size_t idx = 0, stride = 1;
double w = 0.0;
apply_lin_x<detail::xlin, 0, double, Args...>(idx, stride, w, args...);
if (stride) {
storage_.weighted_increase(idx, w);
}
}
template <template <class, class> class Lin, unsigned D>
inline void apply_lin(std::size_t &, std::size_t &) const {}
template <template <class, class> class Lin, unsigned D, typename First, template <template <class, class> class Lin, unsigned D, typename First,
typename... Rest> typename... Rest>
inline void apply_lin(std::size_t &idx, std::size_t &stride, const First &x, inline void apply_lin(std::size_t &idx, std::size_t &stride, const First &x,
@ -214,30 +229,34 @@ private:
return apply_lin<Lin, D + 1, Rest...>(idx, stride, rest...); return apply_lin<Lin, D + 1, Rest...>(idx, stride, rest...);
} }
template <template <class, class> class Lin, unsigned D> template <template <class, class> class Lin, unsigned D, typename X>
inline void apply_lin(std::size_t &idx, std::size_t &stride) const {} inline void apply_lin_x(std::size_t &, std::size_t &, X &) const {}
template <template <class, class> class Lin, unsigned D, typename First, template <template <class, class> class Lin, unsigned D, typename X,
typename... Rest> typename First, typename... Rest>
inline typename std::enable_if<!(std::is_same<First, weight>::value)>::type inline typename std::enable_if<!(std::is_same<First, weight>::value || std::is_same<First, count>::value)>::type
apply_lin_w(std::size_t &idx, std::size_t &stride, double &w, const First &x, apply_lin_x(std::size_t &idx, std::size_t &stride, X &x, const First &first,
const Rest &... rest) const { const Rest &... rest) const {
Lin<typename fusion::result_of::value_at_c<axes_type, D>::type, Lin<typename fusion::result_of::value_at_c<axes_type, D>::type,
First>::apply(idx, stride, fusion::at_c<D>(axes_), x); First>::apply(idx, stride, fusion::at_c<D>(axes_), first);
return apply_lin_w<Lin, D + 1, Rest...>(idx, stride, w, rest...); return apply_lin_x<Lin, D + 1, X, Rest...>(idx, stride, x, rest...);
} }
template <template <class, class> class Lin, unsigned D, typename, template <template <class, class> class Lin, unsigned D, typename X, typename,
typename... Rest> typename... Rest>
inline void apply_lin_w(std::size_t &idx, std::size_t &stride, double &w, inline void apply_lin_x(std::size_t &idx, std::size_t &stride, X &x,
const weight &x, const Rest &... rest) const { const weight &first, const Rest &... rest) const {
w = static_cast<double>(x); x = static_cast<X>(first);
return apply_lin_w<Lin, D, Rest...>(idx, stride, w, rest...); return apply_lin_x<Lin, D, X, Rest...>(idx, stride, x, rest...);
} }
template <template <class, class> class Lin, unsigned D> template <template <class, class> class Lin, unsigned D, typename X, typename,
inline void apply_lin_w(std::size_t &idx, std::size_t &stride, typename... Rest>
double &w) const {} inline void apply_lin_x(std::size_t &idx, std::size_t &stride, X &x,
const count &first, const Rest &... rest) const {
x = static_cast<X>(first);
return apply_lin_x<Lin, D, X, Rest...>(idx, stride, x, rest...);
}
template <typename D, typename A, typename S> friend class histogram; template <typename D, typename A, typename S> friend class histogram;

View File

@ -188,8 +188,15 @@ public:
apply_visitor(increase_visitor(i, buffer_), buffer_); apply_visitor(increase_visitor(i, buffer_), buffer_);
} }
void increase(std::size_t i, value_type w) { template <typename Value>
apply_visitor(wincrease_visitor(i, w, buffer_), buffer_); void increase(std::size_t i, const Value& n) {
apply_visitor(
add_visitor<Value>(i, n, buffer_),
buffer_);
}
void weighted_increase(std::size_t i, value_type weight) {
apply_visitor(wincrease_visitor(i, weight, buffer_), buffer_);
} }
value_type value(std::size_t i) const { value_type value(std::size_t i) const {
@ -200,14 +207,6 @@ public:
return apply_visitor(variance_visitor(i), buffer_); return apply_visitor(variance_visitor(i), buffer_);
} }
template <typename S> adaptive_storage &operator+=(const S &rhs) {
for (std::size_t i = 0, n = rhs.size(); i < n; ++i)
apply_visitor(
add_visitor<typename S::value_type>(i, rhs.value(i), buffer_),
buffer_);
return *this;
}
bool operator==(const adaptive_storage &rhs) const { bool operator==(const adaptive_storage &rhs) const {
return apply_visitor(bicmp_visitor(), buffer_, rhs.buffer_); return apply_visitor(bicmp_visitor(), buffer_, rhs.buffer_);
} }
@ -359,7 +358,7 @@ private:
void operator()(array<void> &b) const { void operator()(array<void> &b) const {
if (value > 0) { if (value > 0) {
buffer = array<uint8_t>(b.size); buffer = array<uint8_t>(b.size);
(*this)(get<array<uint8_t>>(buffer)); operator()(get<array<uint8_t>>(buffer));
} }
} }

View File

@ -49,16 +49,16 @@ public:
container_storage(container_storage &&) = default; container_storage(container_storage &&) = default;
container_storage &operator=(container_storage &&) = default; container_storage &operator=(container_storage &&) = default;
template <typename OtherStorage, typename = detail::is_storage<OtherStorage>> template <typename S, typename = detail::is_storage<S>>
explicit container_storage(const OtherStorage &other) { explicit container_storage(const S &other) {
detail::init(container_, other.size()); detail::init(container_, other.size());
for (std::size_t i = 0; i < container_.size(); ++i) { for (std::size_t i = 0; i < container_.size(); ++i) {
container_[i] = other.value(i); container_[i] = other.value(i);
} }
} }
template <typename OtherStorage> template <typename S>
container_storage &operator=(const OtherStorage &other) { container_storage &operator=(const S &other) {
detail::init(container_, other.size()); detail::init(container_, other.size());
for (std::size_t i = 0; i < container_.size(); ++i) { for (std::size_t i = 0; i < container_.size(); ++i) {
container_[i] = other.value(i); container_[i] = other.value(i);
@ -68,15 +68,10 @@ public:
std::size_t size() const { return container_.size(); } std::size_t size() const { return container_.size(); }
void increase(std::size_t i) { ++(container_[i]); } void increase(std::size_t i) { ++(container_[i]); }
void increase(std::size_t i, value_type w) { container_[i] += w; } template <typename Value>
void increase(std::size_t i, const Value& n) { container_[i] += n; }
value_type value(std::size_t i) const { return container_[i]; } value_type value(std::size_t i) const { return container_[i]; }
template <typename OtherStorage> void operator+=(const OtherStorage &other) {
for (std::size_t i = 0; i < container_.size(); ++i) {
container_[i] += other.value(i);
}
}
template <typename C> bool operator==(const container_storage<C> &rhs) { template <typename C> bool operator==(const container_storage<C> &rhs) {
return container_.size() == rhs.container_.size() && return container_.size() == rhs.container_.size() &&
std::equal(container_.begin(), container_.end(), std::equal(container_.begin(), container_.end(),

View File

@ -22,7 +22,7 @@ template <typename T> adaptive_storage<> prepare(unsigned n = 1) {
s.increase(0); s.increase(0);
const auto tmax = std::numeric_limits<T>::max(); const auto tmax = std::numeric_limits<T>::max();
while (s.value(0) < 0.1 * tmax) { while (s.value(0) < 0.1 * tmax) {
s += s; s.increase(0, s.value(0));
} }
return s; return s;
} }
@ -34,7 +34,7 @@ template <> adaptive_storage<> prepare<void>(unsigned n) {
template <> adaptive_storage<> prepare<detail::weight>(unsigned n) { template <> adaptive_storage<> prepare<detail::weight>(unsigned n) {
adaptive_storage<> s(n); adaptive_storage<> s(n);
s.increase(0, 1.0); s.weighted_increase(0, 1.0);
return s; return s;
} }
@ -44,7 +44,7 @@ template <> adaptive_storage<> prepare<detail::mp_int>(unsigned n) {
auto tmax = static_cast<double>(std::numeric_limits<uint64_t>::max()); auto tmax = static_cast<double>(std::numeric_limits<uint64_t>::max());
tmax *= 2.0; tmax *= 2.0;
while (s.value(0) < tmax) { while (s.value(0) < tmax) {
s += s; s.increase(0, s.value(0));
} }
return s; return s;
} }
@ -170,8 +170,8 @@ template <typename T> void increase_and_grow_impl() {
adaptive_storage<> x(2); adaptive_storage<> x(2);
x.increase(0); x.increase(0);
n2 += x; n2.increase(0, x.value(0));
n2 += x; n2.increase(0, x.value(0));
double v = tmax; double v = tmax;
++v; ++v;
@ -207,7 +207,7 @@ template <typename T> void convert_container_storage_impl() {
BOOST_TEST(!(b == s)); BOOST_TEST(!(b == s));
auto c = aref; auto c = aref;
c += s; c.increase(0, s.value(0));
BOOST_TEST_EQ(c.value(0), 1.0); BOOST_TEST_EQ(c.value(0), 1.0);
BOOST_TEST(c == s); BOOST_TEST(c == s);
BOOST_TEST(s == c); BOOST_TEST(s == c);
@ -215,7 +215,7 @@ template <typename T> void convert_container_storage_impl() {
container_storage<std::vector<float>> t(1); container_storage<std::vector<float>> t(1);
t.increase(0); t.increase(0);
while (t.value(0) < 1e20) while (t.value(0) < 1e20)
t += t; t.increase(0, t.value(0));
auto d = aref; auto d = aref;
d = t; d = t;
BOOST_TEST(d == t); BOOST_TEST(d == t);
@ -234,7 +234,7 @@ template <typename T> void convert_container_storage_impl() {
BOOST_TEST(!(f == s)); BOOST_TEST(!(f == s));
auto g = aref; auto g = aref;
g += s; g.increase(0, s.value(0));
BOOST_TEST_EQ(g.value(0), 1.0); BOOST_TEST_EQ(g.value(0), 1.0);
BOOST_TEST(g == s); BOOST_TEST(g == s);
BOOST_TEST(s == g); BOOST_TEST(s == g);
@ -261,7 +261,7 @@ template <> void convert_container_storage_impl<void>() {
BOOST_TEST(!(a == s)); BOOST_TEST(!(a == s));
auto c = aref; auto c = aref;
c += s; c.increase(0, s.value(0));
BOOST_TEST_EQ(c.value(0), 1.0); BOOST_TEST_EQ(c.value(0), 1.0);
BOOST_TEST(c == s); BOOST_TEST(c == s);
BOOST_TEST(s == c); BOOST_TEST(s == c);
@ -330,23 +330,23 @@ int main() {
double x = 1.0; double x = 1.0;
adaptive_storage<> y(1); adaptive_storage<> y(1);
BOOST_TEST_EQ(y.value(0), 0.0); BOOST_TEST_EQ(y.value(0), 0.0);
a += y; a.increase(0, y.value(0));
BOOST_TEST_EQ(a.value(0), x); BOOST_TEST_EQ(a.value(0), x);
for (unsigned i = 0; i < 80; ++i) { for (unsigned i = 0; i < 80; ++i) {
a += a; a.increase(0, a.value(0));
x += x; x += x;
adaptive_storage<> b(1); adaptive_storage<> b(1);
b += a; b.increase(0, a.value(0));
BOOST_TEST_EQ(a.value(0), x); BOOST_TEST_EQ(a.value(0), x);
BOOST_TEST_EQ(a.variance(0), x); BOOST_TEST_EQ(a.variance(0), x);
BOOST_TEST_EQ(b.value(0), x); BOOST_TEST_EQ(b.value(0), x);
BOOST_TEST_EQ(b.variance(0), x); BOOST_TEST_EQ(b.variance(0), x);
b.increase(0, 0.0); b.weighted_increase(0, 0.0);
BOOST_TEST_EQ(b.value(0), x); BOOST_TEST_EQ(b.value(0), x);
BOOST_TEST_EQ(b.variance(0), x); BOOST_TEST_EQ(b.variance(0), x);
adaptive_storage<> c(1); adaptive_storage<> c(1);
c.increase(0, 0.0); c.weighted_increase(0, 0.0);
c += a; c.increase(0, a.value(0));
BOOST_TEST_EQ(c.value(0), x); BOOST_TEST_EQ(c.value(0), x);
BOOST_TEST_EQ(c.variance(0), x); BOOST_TEST_EQ(c.variance(0), x);
} }

View File

@ -201,25 +201,25 @@ template <typename Type> void run_tests() {
h.fill(0); h.fill(0);
h.fill(0); h.fill(0);
h.fill(-1); h.fill(-1);
h.fill(10); h.fill(10, count(10));
BOOST_TEST_EQ(h.dim(), 1); BOOST_TEST_EQ(h.dim(), 1);
BOOST_TEST_EQ(bins(h.axis(0_c)), 2); BOOST_TEST_EQ(bins(h.axis(0_c)), 2);
BOOST_TEST_EQ(shape(h.axis(0_c)), 4); BOOST_TEST_EQ(shape(h.axis(0_c)), 4);
BOOST_TEST_EQ(h.sum(), 4); BOOST_TEST_EQ(h.sum(), 13);
BOOST_TEST_THROWS(h.value(-2), std::out_of_range); BOOST_TEST_THROWS(h.value(-2), std::out_of_range);
BOOST_TEST_EQ(h.value(-1), 1.0); BOOST_TEST_EQ(h.value(-1), 1.0);
BOOST_TEST_EQ(h.value(0), 2.0); BOOST_TEST_EQ(h.value(0), 2.0);
BOOST_TEST_EQ(h.value(1), 0.0); BOOST_TEST_EQ(h.value(1), 0.0);
BOOST_TEST_EQ(h.value(2), 1.0); BOOST_TEST_EQ(h.value(2), 10.0);
BOOST_TEST_THROWS(h.value(3), std::out_of_range); BOOST_TEST_THROWS(h.value(3), std::out_of_range);
BOOST_TEST_THROWS(h.variance(-2), std::out_of_range); BOOST_TEST_THROWS(h.variance(-2), std::out_of_range);
BOOST_TEST_EQ(h.variance(-1), 1.0); BOOST_TEST_EQ(h.variance(-1), 1.0);
BOOST_TEST_EQ(h.variance(0), 2.0); BOOST_TEST_EQ(h.variance(0), 2.0);
BOOST_TEST_EQ(h.variance(1), 0.0); BOOST_TEST_EQ(h.variance(1), 0.0);
BOOST_TEST_EQ(h.variance(2), 1.0); BOOST_TEST_EQ(h.variance(2), 10.0);
BOOST_TEST_THROWS(h.variance(3), std::out_of_range); BOOST_TEST_THROWS(h.variance(3), std::out_of_range);
} }
@ -230,7 +230,7 @@ template <typename Type> void run_tests() {
h.fill(0); h.fill(0);
h.fill(-0); h.fill(-0);
h.fill(-1); h.fill(-1);
h.fill(10); h.fill(10, count(10));
BOOST_TEST_EQ(h.dim(), 1); BOOST_TEST_EQ(h.dim(), 1);
BOOST_TEST_EQ(bins(h.axis(0_c)), 2); BOOST_TEST_EQ(bins(h.axis(0_c)), 2);
@ -276,10 +276,10 @@ template <typename Type> void run_tests() {
auto h = make_histogram<container_storage<std::vector<float>>>( auto h = make_histogram<container_storage<std::vector<float>>>(
Type(), regular_axis<>(2, -1, 1)); Type(), regular_axis<>(2, -1, 1));
h.fill(0); h.fill(0);
h.fill(weight(2.0), -1.0); h.fill(count(2.0), -1.0);
h.fill(-1.0); h.fill(-1.0);
h.fill(-2.0); h.fill(-2.0);
h.fill(weight(5.0), 10.0); h.fill(count(5.0), 10.0);
BOOST_TEST_EQ(h.sum(), 10); BOOST_TEST_EQ(h.sum(), 10);