mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-11 05:07:58 +00:00
improving and testing operators
This commit is contained in:
parent
371cbc9385
commit
5dee79f556
@ -13,7 +13,6 @@
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/utility/string_view.hpp>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
@ -127,7 +126,7 @@ protected:
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const axis_base &rhs) const {
|
||||
bool operator==(const axis_base &rhs) const noexcept {
|
||||
return size_ == rhs.size_ && label_ == rhs.label_;
|
||||
}
|
||||
|
||||
@ -167,7 +166,7 @@ protected:
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const axis_base_uoflow &rhs) const {
|
||||
bool operator==(const axis_base_uoflow &rhs) const noexcept {
|
||||
return axis_base::operator==(rhs) && shape_ == rhs.shape_;
|
||||
}
|
||||
|
||||
@ -182,28 +181,28 @@ namespace transform {
|
||||
struct identity {
|
||||
template <typename T> static T forward(T v) { return v; }
|
||||
template <typename T> static T inverse(T v) { return v; }
|
||||
bool operator==(const identity &) const { return true; }
|
||||
bool operator==(const identity &) const noexcept { return true; }
|
||||
template <class Archive> void serialize(Archive &, unsigned) {}
|
||||
};
|
||||
|
||||
struct log {
|
||||
template <typename T> static T forward(T v) { return std::log(v); }
|
||||
template <typename T> static T inverse(T v) { return std::exp(v); }
|
||||
bool operator==(const log &) const { return true; }
|
||||
bool operator==(const log &) const noexcept { return true; }
|
||||
template <class Archive> void serialize(Archive &, unsigned) {}
|
||||
};
|
||||
|
||||
struct sqrt {
|
||||
template <typename T> static T forward(T v) { return std::sqrt(v); }
|
||||
template <typename T> static T inverse(T v) { return v * v; }
|
||||
bool operator==(const sqrt &) const { return true; }
|
||||
bool operator==(const sqrt &) const noexcept { return true; }
|
||||
template <class Archive> void serialize(Archive &, unsigned) {}
|
||||
};
|
||||
|
||||
struct cos {
|
||||
template <typename T> static T forward(T v) { return std::cos(v); }
|
||||
template <typename T> static T inverse(T v) { return std::acos(v); }
|
||||
bool operator==(const cos &) const { return true; }
|
||||
bool operator==(const cos &) const noexcept { return true; }
|
||||
template <class Archive> void serialize(Archive &, unsigned) {}
|
||||
};
|
||||
|
||||
@ -215,7 +214,7 @@ struct pow {
|
||||
return std::pow(v, 1.0 / value);
|
||||
}
|
||||
double value = 1.0;
|
||||
bool operator==(const pow &other) const { return value == other.value; }
|
||||
bool operator==(const pow &other) const noexcept { return value == other.value; }
|
||||
template <class Archive> void serialize(Archive &, unsigned);
|
||||
};
|
||||
} // namespace transform
|
||||
@ -226,8 +225,7 @@ struct pow {
|
||||
* Very fast. Binning is a O(1) operation.
|
||||
*/
|
||||
template <typename RealType = double, typename Transform = transform::identity>
|
||||
class regular : public axis_base_uoflow, Transform,
|
||||
boost::operators<regular<RealType, Transform>> {
|
||||
class regular : public axis_base_uoflow, Transform {
|
||||
public:
|
||||
using value_type = RealType;
|
||||
using bin_type = interval<value_type>;
|
||||
@ -315,7 +313,7 @@ private:
|
||||
* bins for this axis. Binning is a O(1) operation.
|
||||
*/
|
||||
template <typename RealType = double>
|
||||
class circular : public axis_base, boost::operators<regular<RealType>> {
|
||||
class circular : public axis_base {
|
||||
public:
|
||||
using value_type = RealType;
|
||||
using bin_type = interval<value_type>;
|
||||
@ -355,7 +353,7 @@ public:
|
||||
return {eval(idx), eval(idx + 1)};
|
||||
}
|
||||
|
||||
bool operator==(const circular &o) const {
|
||||
bool operator==(const circular &o) const noexcept {
|
||||
return axis_base::operator==(o) && phase_ == o.phase_ &&
|
||||
perimeter_ == o.perimeter_;
|
||||
}
|
||||
@ -380,7 +378,7 @@ private:
|
||||
* and the problem domain allows it, prefer a regular.
|
||||
*/
|
||||
template <typename RealType = double>
|
||||
class variable : public axis_base_uoflow, boost::operators<variable<RealType>> {
|
||||
class variable : public axis_base_uoflow {
|
||||
public:
|
||||
using value_type = RealType;
|
||||
using bin_type = interval<value_type>;
|
||||
@ -448,7 +446,7 @@ public:
|
||||
return {eval(idx), eval(idx + 1)};
|
||||
}
|
||||
|
||||
bool operator==(const variable &o) const {
|
||||
bool operator==(const variable &o) const noexcept {
|
||||
if (!axis_base_uoflow::operator==(o)) {
|
||||
return false;
|
||||
}
|
||||
@ -476,7 +474,7 @@ private:
|
||||
* faster than a regular.
|
||||
*/
|
||||
template <typename IntType = int>
|
||||
class integer : public axis_base_uoflow, boost::operators<integer<IntType>> {
|
||||
class integer : public axis_base_uoflow {
|
||||
public:
|
||||
using value_type = IntType;
|
||||
using bin_type = interval<value_type>;
|
||||
@ -510,7 +508,7 @@ public:
|
||||
/// Returns the integer that is mapped to the bin index.
|
||||
bin_type operator[](int idx) const { return {min_ + idx, min_ + idx + 1}; }
|
||||
|
||||
bool operator==(const integer &o) const {
|
||||
bool operator==(const integer &o) const noexcept {
|
||||
return axis_base_uoflow::operator==(o) && min_ == o.min_;
|
||||
}
|
||||
|
||||
@ -537,7 +535,7 @@ private:
|
||||
* Binning is a O(1) operation. The value type must be hashable.
|
||||
*/
|
||||
template <typename T = int>
|
||||
class category : public axis_base, boost::operators<category<T>> {
|
||||
class category : public axis_base {
|
||||
using map_type = bimap<T, int>;
|
||||
|
||||
public:
|
||||
@ -597,9 +595,9 @@ public:
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool operator==(const category &other) const {
|
||||
return axis_base::operator==(other) &&
|
||||
std::equal(map_->begin(), map_->end(), other.map_->begin());
|
||||
bool operator==(const category &o) const noexcept {
|
||||
return axis_base::operator==(o) &&
|
||||
std::equal(map_->begin(), map_->end(), o.map_->begin());
|
||||
}
|
||||
|
||||
const_iterator begin() const { return const_iterator(*this, 0); }
|
||||
|
@ -43,13 +43,16 @@ template <typename T, typename = decltype(std::begin(std::declval<T &>()),
|
||||
std::end(std::declval<T &>()))>
|
||||
struct is_sequence {};
|
||||
|
||||
template <typename MainVector, typename AuxVector> struct combine {
|
||||
template <typename MainVector, typename AuxVector> struct combiner {
|
||||
using type =
|
||||
typename mpl::copy_if<AuxVector,
|
||||
mpl::not_<mpl::contains<MainVector, mpl::_1>>,
|
||||
mpl::back_inserter<MainVector>>::type;
|
||||
};
|
||||
|
||||
template <typename MainVector, typename AuxVector>
|
||||
using combine = typename combiner<MainVector, AuxVector>::type;
|
||||
|
||||
struct bool_mask_op {
|
||||
std::vector<bool> &b;
|
||||
bool v;
|
||||
|
@ -65,6 +65,47 @@ inline detail::keep_dynamic keep(unsigned i, Rest... rest) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// fast operators (boost::operators does not use rvalue references yet)
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> && operator+(histogram<Variant, Axes, Storage> &&a,
|
||||
const histogram<Variant, Axes, Storage> &b)
|
||||
{ a+=b; return std::move(a); }
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage>&& operator+(histogram<Variant, Axes, Storage> &&a,
|
||||
histogram<Variant, Axes, Storage> &&b)
|
||||
{ a+=b; return std::move(a); }
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage>&& operator+(const histogram<Variant, Axes, Storage> &a,
|
||||
histogram<Variant, Axes, Storage> &&b)
|
||||
{ b+=a; return std::move(b); }
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> operator+(const histogram<Variant, Axes, Storage> &a,
|
||||
const histogram<Variant, Axes, Storage> &b)
|
||||
{ histogram<Variant, Axes, Storage> r(a); r+=b; return r; }
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage>&& operator*(histogram<Variant, Axes, Storage> &&a,
|
||||
const double x)
|
||||
{ a*=x; return std::move(a); }
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage>&& operator*(const double x,
|
||||
histogram<Variant, Axes, Storage> &&b)
|
||||
{ b*=x; return std::move(b); }
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> operator*(const histogram<Variant, Axes, Storage> &a,
|
||||
const double x)
|
||||
{ histogram<Variant, Axes, Storage> r(a); r*=x; return r; }
|
||||
|
||||
template <typename Variant, typename Axes, typename Storage>
|
||||
histogram<Variant, Axes, Storage> operator*(const double x,
|
||||
const histogram<Variant, Axes, Storage> &b)
|
||||
{ histogram<Variant, Axes, Storage> r(b); r*=x; return r; }
|
||||
|
||||
} // namespace histogram
|
||||
} // namespace boost
|
||||
|
||||
|
@ -431,22 +431,22 @@ private:
|
||||
|
||||
template <typename... Axes>
|
||||
inline histogram<
|
||||
Dynamic, typename detail::combine<builtin_axes, mpl::vector<Axes...>>::type>
|
||||
Dynamic, detail::combine<builtin_axes, mpl::vector<Axes...>>>
|
||||
make_dynamic_histogram(Axes &&... axes) {
|
||||
|
||||
return histogram<Dynamic, typename detail::combine<
|
||||
builtin_axes, mpl::vector<Axes...>>::type>(
|
||||
return histogram<Dynamic, detail::combine<
|
||||
builtin_axes, mpl::vector<Axes...>>>(
|
||||
std::forward<Axes>(axes)...);
|
||||
}
|
||||
|
||||
template <typename Storage, typename... Axes>
|
||||
inline histogram<
|
||||
Dynamic, typename detail::combine<builtin_axes, mpl::vector<Axes...>>::type,
|
||||
Dynamic, detail::combine<builtin_axes, mpl::vector<Axes...>>,
|
||||
Storage>
|
||||
make_dynamic_histogram_with(Axes &&... axes) {
|
||||
return histogram<
|
||||
Dynamic,
|
||||
typename detail::combine<builtin_axes, mpl::vector<Axes...>>::type,
|
||||
detail::combine<builtin_axes, mpl::vector<Axes...>>,
|
||||
Storage>(std::forward<Axes>(axes)...);
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,6 @@
|
||||
#ifndef _BOOST_HISTOGRAM_HISTOGRAM_IMPL_STATIC_HPP_
|
||||
#define _BOOST_HISTOGRAM_HISTOGRAM_IMPL_STATIC_HPP_
|
||||
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/fusion/adapted/mpl.hpp>
|
||||
#include <boost/fusion/algorithm.hpp>
|
||||
#include <boost/fusion/algorithm/iteration/for_each.hpp>
|
||||
|
@ -532,6 +532,32 @@ template <typename Type> void run_tests() {
|
||||
BOOST_TEST_EQ(h.sum(), 20.0);
|
||||
}
|
||||
|
||||
// operators
|
||||
{
|
||||
auto a = make_histogram<adaptive_storage>(Type(), axis::integer<>(0, 3));
|
||||
auto b = a;
|
||||
a.fill(0);
|
||||
b.fill(1);
|
||||
auto c = a + b;
|
||||
BOOST_TEST_EQ(c.value(0), 1.0);
|
||||
BOOST_TEST_EQ(c.value(1), 1.0);
|
||||
c += b;
|
||||
BOOST_TEST_EQ(c.value(0), 1.0);
|
||||
BOOST_TEST_EQ(c.value(1), 2.0);
|
||||
auto d = 3 * a;
|
||||
auto e = b * 2;
|
||||
BOOST_TEST_EQ(d.value(0), 3.0);
|
||||
BOOST_TEST_EQ(d.value(1), 0.0);
|
||||
BOOST_TEST_EQ(e.value(0), 0.0);
|
||||
BOOST_TEST_EQ(e.value(1), 2.0);
|
||||
auto r = a;
|
||||
r += b;
|
||||
r += d;
|
||||
BOOST_TEST_EQ(r.value(0), 4.0);
|
||||
BOOST_TEST_EQ(r.value(1), 1.0);
|
||||
BOOST_TEST_EQ(r, a + b + 3 * a);
|
||||
}
|
||||
|
||||
// histogram_serialization
|
||||
{
|
||||
enum { A, B, C };
|
||||
@ -679,7 +705,7 @@ template <typename T1, typename T2> void run_mixed_tests() {
|
||||
{
|
||||
auto a = make_histogram<adaptive_storage>(T1{}, axis::regular<>{3, 0, 3},
|
||||
axis::integer<>(0, 2));
|
||||
auto b = make_histogram<adaptive_storage>(T2{}, axis::regular<>{3, 0, 3},
|
||||
auto b = make_histogram<array_storage<int>>(T2{}, axis::regular<>{3, 0, 3},
|
||||
axis::integer<>(0, 2));
|
||||
BOOST_TEST_EQ(a, b);
|
||||
auto b2 = make_histogram<adaptive_storage>(T2{}, axis::integer<>{0, 3},
|
||||
@ -694,7 +720,7 @@ template <typename T1, typename T2> void run_mixed_tests() {
|
||||
{
|
||||
auto a = make_histogram<adaptive_storage>(T1{}, axis::regular<>{3, 0, 3},
|
||||
axis::integer<>(0, 2));
|
||||
auto b = make_histogram<adaptive_storage>(T2{}, axis::regular<>{3, 0, 3},
|
||||
auto b = make_histogram<array_storage<int>>(T2{}, axis::regular<>{3, 0, 3},
|
||||
axis::integer<>(0, 2));
|
||||
a.fill(1, 1);
|
||||
BOOST_TEST_NE(a, b);
|
||||
|
Loading…
x
Reference in New Issue
Block a user