make realtype a template parameter

This commit is contained in:
Hans Dembinski 2017-03-16 09:15:34 +01:00
parent f101aafc42
commit 181a88e7da
13 changed files with 220 additions and 207 deletions

View File

@ -20,7 +20,7 @@ namespace bh = boost::histogram;
int main() {
// create a 1d-histogram in default configuration which
// covers the real line from -1 to 1 in 100 bins
auto h = bh::make_static_histogram(bh::regular_axis(100, -1, 1));
auto h = bh::make_static_histogram(bh::regular_axis<>(100, -1, 1));
// do something with h
}
``
@ -39,8 +39,8 @@ namespace bh = boost::histogram;
int main() {
// create a 2d-histogram in default configuration with an "age" axis
// and an "income" axis
auto h = bh::make_static_histogram(bh::regular_axis(20, 0, 100, "age in years"),
bh::regular_axis(20, 0, 100, "yearly income in $1000"));
auto h = bh::make_static_histogram(bh::regular_axis<>(20, 0, 100, "age in years"),
bh::regular_axis<>(20, 0, 100, "yearly income in $1000"));
// do something with h
}
``
@ -88,7 +88,7 @@ namespace bh = boost::histogram;
int main() {
auto v = std::vector<bh::dynamic_histogram<>::axis_type>();
v.push_back(bh::regular_axis(100, -1, 1));
v.push_back(bh::regular_axis<>(100, -1, 1));
v.push_back(bh::integer_axis(1, 6));
auto h = bh::dynamic_histogram<>(v.begin(), v.end());
// do something with h
@ -120,8 +120,8 @@ int main() {
random::mt19937 gen;
random::normal_distribution<> norm();
auto h = histogram::make_static_histogram(
histogram::regular_axis(100, -5, 5, "x"),
histogram::regular_axis(100, -5, 5, "y")
histogram::regular_axis<>(100, -5, 5, "x"),
histogram::regular_axis<>(100, -5, 5, "y")
);
for (int i = 0; i < 1000; ++i)
h.fill(norm(gen), norm(gen));
@ -173,4 +173,4 @@ The histogram can be serialized to disk for persistent storage from C++ and pick
[endsect]
[endsect]
[endsect]

View File

@ -141,4 +141,4 @@ Serialization is implemented using [@boost:/libs/serialization/index.html Boost.
[endsect]
[endsect]
[endsect]

View File

@ -98,4 +98,4 @@ Example 2: How to make, fill, and use a 2d-histogram in Python.
# [ 0 0 0 0]]
```
[endsect]
[endsect]

View File

@ -21,7 +21,7 @@ namespace boost {
namespace histogram {
/// Common base class for most axes.
class axis_with_label {
class axis_base {
public:
/// Returns the number of bins, excluding overflow/underflow.
inline int bins() const { return size_ ; }
@ -35,20 +35,20 @@ public:
void label(const std::string& label) { label_ = label; }
protected:
axis_with_label(unsigned n, const std::string& label, bool uoflow) :
axis_base(unsigned n, const std::string& label, bool uoflow) :
size_(n), shape_(size_ + 2 * uoflow), label_(label)
{
if (n == 0)
throw std::logic_error("bins > 0 required");
}
axis_with_label() = default;
axis_with_label(const axis_with_label&) = default;
axis_with_label(axis_with_label&&) = default;
axis_with_label& operator=(const axis_with_label&) = default;
axis_with_label& operator=(axis_with_label&&) = default;
axis_base() = default;
axis_base(const axis_base&) = default;
axis_base(axis_base&&) = default;
axis_base& operator=(const axis_base&) = default;
axis_base& operator=(axis_base&&) = default;
bool operator==(const axis_with_label& o) const
bool operator==(const axis_base& o) const
{ return size_ == o.size_ && shape_ == o.shape_ && label_ == o.label_; }
private:
@ -57,22 +57,20 @@ private:
std::string label_;
template <class Archive>
friend void serialize(Archive&, axis_with_label&, unsigned);
friend void serialize(Archive&, axis_base&, unsigned);
};
/// Mixin for real-valued axes.
template <typename Derived>
template <typename RealType, typename Derived>
class real_axis {
public:
typedef double value_type;
/// Lower edge of the bin (left side).
double left(int idx) const {
RealType left(int idx) const {
return static_cast<const Derived&>(*this)[idx];
}
/// Upper edge of the bin (right side).
double right(int idx) const {
RealType right(int idx) const {
return static_cast<const Derived&>(*this)[idx + 1];
}
};
@ -82,9 +80,12 @@ public:
* The simplest and common binning strategy.
* Very fast. Binning is a O(1) operation.
*/
class regular_axis: public axis_with_label,
public real_axis<regular_axis> {
template <typename RealType=double>
class regular_axis: public axis_base,
public real_axis<RealType, regular_axis<RealType>> {
public:
using value_type = RealType;
/** Construct axis with n bins over range [min, max).
*
* \param n number of bins.
@ -93,10 +94,10 @@ public:
* \param label description of the axis.
* \param uoflow whether to add under-/overflow bins.
*/
regular_axis(unsigned n, double min, double max,
regular_axis(unsigned n, value_type min, value_type max,
const std::string& label = std::string(),
bool uoflow = true) :
axis_with_label(n, label, uoflow),
axis_base(n, label, uoflow),
min_(min),
delta_((max - min) / n)
{
@ -111,36 +112,36 @@ public:
regular_axis& operator=(regular_axis&&) = default;
/// Returns the bin index for the passed argument.
inline int index(double x) const
inline int index(value_type x) const
{
// Optimized code
const double z = (x - min_) / delta_;
const value_type z = (x - min_) / delta_;
return z >= 0.0 ? (z > bins() ? bins() : static_cast<int>(z)) : -1;
}
/// Returns the starting edge of the bin.
double operator[](int idx) const
value_type operator[](int idx) const
{
if (idx < 0)
return -std::numeric_limits<double>::infinity();
return -std::numeric_limits<value_type>::infinity();
if (idx > bins())
return std::numeric_limits<double>::infinity();
const double z = double(idx) / bins();
return std::numeric_limits<value_type>::infinity();
const value_type z = value_type(idx) / bins();
return (1.0 - z) * min_ + z * (min_ + delta_ * bins());
}
bool operator==(const regular_axis& o) const
{
return axis_with_label::operator==(o) &&
return axis_base::operator==(o) &&
min_ == o.min_ &&
delta_ == o.delta_;
}
private:
double min_, delta_;
value_type min_, delta_;
template <class Archive>
friend void serialize(Archive&, regular_axis&, unsigned);
template <class Archive, typename RealType1>
friend void serialize(Archive&, regular_axis<RealType1>&, unsigned);
};
/** Axis for real-valued angles.
@ -150,9 +151,12 @@ private:
* \f$2 \pi\f$.
* Binning is a O(1) operation.
*/
class polar_axis: public axis_with_label,
public real_axis<polar_axis> {
template <typename RealType=double>
class polar_axis: public axis_base,
public real_axis<RealType, polar_axis<RealType>> {
public:
using value_type = RealType;
/** Constructor for n bins with an optional offset.
*
* \param n number of bins.
@ -160,9 +164,9 @@ public:
* \param label description of the axis.
*/
explicit
polar_axis(unsigned n, double start = 0.0,
polar_axis(unsigned n, value_type start = 0.0,
const std::string& label = std::string()) :
axis_with_label(n, label, false),
axis_base(n, label, false),
start_(start)
{}
@ -173,29 +177,29 @@ public:
polar_axis& operator=(polar_axis&&) = default;
/// Returns the bin index for the passed argument.
inline int index(double x) const {
inline int index(value_type x) const {
using namespace boost::math::double_constants;
const double z = (x - start_) / two_pi;
const value_type z = (x - start_) / two_pi;
const int i = static_cast<int>(std::floor(z * bins())) % bins();
return i + (i < 0) * bins();
}
/// Returns the starting edge of the bin.
double operator[](int idx) const
value_type operator[](int idx) const
{
using namespace boost::math::double_constants;
const double z = double(idx) / bins();
const value_type z = value_type(idx) / bins();
return z * two_pi + start_;
}
bool operator==(const polar_axis& o) const
{ return axis_with_label::operator==(o) && start_ == o.start_; }
{ return axis_base::operator==(o) && start_ == o.start_; }
private:
double start_;
value_type start_;
template <class Archive>
friend void serialize(Archive&, polar_axis&, unsigned);
template <class Archive, typename RealType1>
friend void serialize(Archive&, polar_axis<RealType1>&, unsigned);
};
/** An axis for real-valued data and bins of varying width.
@ -203,9 +207,12 @@ private:
* Binning is a O(log(N)) operation. If speed matters
* and the problem domain allows it, prefer a regular_axis.
*/
class variable_axis : public axis_with_label,
public real_axis<variable_axis> {
template <typename RealType=double>
class variable_axis : public axis_base,
public real_axis<RealType, variable_axis<RealType>> {
public:
using value_type = RealType;
/** Construct an axis from bin edges.
*
* \param x sequence of bin edges.
@ -213,11 +220,11 @@ public:
* \param uoflow whether to add under-/overflow bins.
*/
explicit
variable_axis(const std::initializer_list<double>& x,
variable_axis(const std::initializer_list<value_type>& x,
const std::string& label = std::string(),
bool uoflow = true) :
axis_with_label(x.size() - 1, label, uoflow),
x_(new double[x.size()])
axis_base(x.size() - 1, label, uoflow),
x_(new value_type[x.size()])
{
if (x.size() < 2)
throw std::logic_error("at least two values required");
@ -225,11 +232,11 @@ public:
std::sort(x_.get(), x_.get() + bins() + 1);
}
variable_axis(const std::vector<double>& x,
variable_axis(const std::vector<value_type>& x,
const std::string& label = std::string(),
bool uoflow = true) :
axis_with_label(x.size() - 1, label, uoflow),
x_(new double[x.size()])
axis_base(x.size() - 1, label, uoflow),
x_(new value_type[x.size()])
{
std::copy(x.begin(), x.end(), x_.get());
std::sort(x_.get(), x_.get() + bins() + 1);
@ -239,8 +246,8 @@ public:
variable_axis(Iterator begin, Iterator end,
const std::string& label = std::string(),
bool uoflow = true) :
axis_with_label(std::distance(begin, end) - 1, label, uoflow),
x_(new double[std::distance(begin, end)])
axis_base(std::distance(begin, end) - 1, label, uoflow),
x_(new value_type[std::distance(begin, end)])
{
std::copy(begin, end, x_.get());
std::sort(x_.get(), x_.get() + bins() + 1);
@ -248,8 +255,8 @@ public:
variable_axis() = default;
variable_axis(const variable_axis& o) :
axis_with_label(o),
x_(new double[bins() + 1])
axis_base(o),
x_(new value_type[bins() + 1])
{
std::copy(o.x_.get(), o.x_.get() + bins() + 1, x_.get());
}
@ -257,8 +264,8 @@ public:
variable_axis& operator=(const variable_axis& o)
{
if (this != &o) {
axis_with_label::operator=(o);
x_.reset(new double[bins() + 1]);
axis_base::operator=(o);
x_.reset(new value_type[bins() + 1]);
std::copy(o.x_.get(), o.x_.get() + bins() + 1, x_.get());
}
return *this;
@ -266,33 +273,33 @@ public:
variable_axis& operator=(variable_axis&&) = default;
/// Returns the bin index for the passed argument.
inline int index(double x) const {
inline int index(value_type x) const {
return std::upper_bound(x_.get(), x_.get() + bins() + 1, x)
- x_.get() - 1;
}
/// Returns the starting edge of the bin.
double operator[](int idx) const
value_type operator[](int idx) const
{
if (idx < 0)
return -std::numeric_limits<double>::infinity();
return -std::numeric_limits<value_type>::infinity();
if (idx > bins())
return std::numeric_limits<double>::infinity();
return std::numeric_limits<value_type>::infinity();
return x_[idx];
}
bool operator==(const variable_axis& o) const
{
if (!axis_with_label::operator==(o))
if (!axis_base::operator==(o))
return false;
return std::equal(x_.get(), x_.get() + bins() + 1, o.x_.get());
}
private:
std::unique_ptr<double[]> x_; // smaller size compared to std::vector
std::unique_ptr<value_type[]> x_; // smaller size compared to std::vector
template <class Archive>
friend void serialize(Archive&, variable_axis&, unsigned);
template <class Archive, typename RealType1>
friend void serialize(Archive&, variable_axis<RealType1>&, unsigned);
};
/** An axis for a contiguous range of integers.
@ -300,19 +307,19 @@ private:
* There are no underflow/overflow bins for this axis.
* Binning is a O(1) operation.
*/
class integer_axis: public axis_with_label {
class integer_axis: public axis_base {
public:
typedef int value_type;
using value_type = int;
/** Construct axis over integer range [min, max].
*
* \param min smallest integer of the covered range.
* \param max largest integer of the covered range.
*/
integer_axis(int min, int max,
integer_axis(value_type min, value_type max,
const std::string& label = std::string(),
bool uoflow = true) :
axis_with_label(max + 1 - min, label, uoflow),
axis_base(max + 1 - min, label, uoflow),
min_(min)
{
if (min > max)
@ -326,22 +333,22 @@ public:
integer_axis& operator=(integer_axis&&) = default;
/// Returns the bin index for the passed argument.
inline int index(int x) const
inline int index(value_type x) const
{
const int z = x - min_;
return z >= 0 ? (z > bins() ? bins() : z) : -1;
}
/// Returns the integer that is mapped to the bin index.
int operator[](int idx) const { return min_ + idx; }
value_type operator[](int idx) const { return min_ + idx; }
bool operator==(const integer_axis& o) const
{
return axis_with_label::operator==(o) && min_ == o.min_;
return axis_base::operator==(o) && min_ == o.min_;
}
private:
int min_;
value_type min_;
template <class Archive>
friend void serialize(Archive&, integer_axis&, unsigned);
@ -428,7 +435,10 @@ private:
};
using default_axes = mpl::vector<
regular_axis, polar_axis, variable_axis, category_axis, integer_axis
regular_axis<double>, regular_axis<float>,
polar_axis<double>, polar_axis<float>,
variable_axis<double>, variable_axis<float>,
integer_axis, category_axis
>::type;
}

View File

@ -15,7 +15,8 @@
namespace boost {
namespace histogram {
inline std::ostream& operator<<(std::ostream& os, const regular_axis& a)
template <typename RealType>
inline std::ostream& operator<<(std::ostream& os, const regular_axis<RealType>& a)
{
os << "regular_axis(" << a.bins() << ", " << a[0] << ", " << a[a.bins()];
if (!detail::empty(a.label())) {
@ -28,7 +29,8 @@ inline std::ostream& operator<<(std::ostream& os, const regular_axis& a)
return os;
}
inline std::ostream& operator<<(std::ostream& os, const polar_axis& a)
template <typename RealType>
inline std::ostream& operator<<(std::ostream& os, const polar_axis<RealType>& a)
{
os << "polar_axis(" << a.bins();
if (a[0] != 0.0)
@ -41,7 +43,8 @@ inline std::ostream& operator<<(std::ostream& os, const polar_axis& a)
return os;
}
inline std::ostream& operator<<(std::ostream& os, const variable_axis& a)
template <typename RealType>
inline std::ostream& operator<<(std::ostream& os, const variable_axis<RealType>& a)
{
os << "variable_axis(" << a[0];
for (int i = 1; i <= a.bins(); ++i)

View File

@ -76,41 +76,41 @@ void adaptive_storage<Allocator>::serialize(Archive& ar, unsigned /* version */)
}
template <class Archive>
inline void serialize(Archive& ar, axis_with_label & base, unsigned /* version */)
inline void serialize(Archive& ar, axis_base & base, unsigned /* version */)
{
ar & base.size_;
ar & base.shape_;
ar & base.label_;
}
template <class Archive>
inline void serialize(Archive& ar, regular_axis & axis, unsigned /* version */)
template <class Archive, typename RealType>
inline void serialize(Archive& ar, regular_axis<RealType> & axis, unsigned /* version */)
{
ar & boost::serialization::base_object<axis_with_label>(axis);
ar & boost::serialization::base_object<axis_base>(axis);
ar & axis.min_;
ar & axis.delta_;
}
template <class Archive>
inline void serialize(Archive& ar, polar_axis & axis, unsigned /* version */)
template <class Archive, typename RealType>
inline void serialize(Archive& ar, polar_axis<RealType> & axis, unsigned /* version */)
{
ar & boost::serialization::base_object<axis_with_label>(axis);
ar & boost::serialization::base_object<axis_base>(axis);
ar & axis.start_;
}
template <class Archive>
inline void serialize(Archive& ar, variable_axis & axis, unsigned /* version */)
template <class Archive, typename RealType>
inline void serialize(Archive& ar, variable_axis<RealType> & axis, unsigned /* version */)
{
ar & boost::serialization::base_object<axis_with_label>(axis);
ar & boost::serialization::base_object<axis_base>(axis);
if (Archive::is_loading::value)
axis.x_.reset(new double[axis.bins() + 1]);
axis.x_.reset(new RealType[axis.bins() + 1]);
ar & boost::serialization::make_array(axis.x_.get(), axis.bins() + 1);
}
template <class Archive>
inline void serialize(Archive& ar, integer_axis & axis, unsigned /* version */)
{
ar & boost::serialization::base_object<axis_with_label>(axis);
ar & boost::serialization::base_object<axis_base>(axis);
ar & axis.min_;
}

View File

@ -132,7 +132,7 @@ struct axis_suite : public python::def_visitor<axis_suite<T> > {
template <typename Class, typename U>
static
typename std::enable_if<std::is_base_of<axis_with_label, U>::value, void>::type
typename std::enable_if<std::is_base_of<axis_base, U>::value>::type
label(Class& cl) {
cl.add_property("label",
make_function((const std::string&(U::*)() const) &U::label,
@ -143,7 +143,7 @@ struct axis_suite : public python::def_visitor<axis_suite<T> > {
template <typename Class, typename U>
static
typename std::enable_if<!std::is_base_of<axis_with_label, U>::value, void>::type
typename std::enable_if<!std::is_base_of<axis_base, U>::value>::type
label(Class& cl) {}
template <class Class>
@ -188,7 +188,7 @@ void register_axis_types()
class_<std::vector<double>::const_iterator>("vector_double_iterator", no_init);
class_<std::vector<std::string>::const_iterator>("vector_string_iterator", no_init);
class_<regular_axis>("regular_axis",
class_<regular_axis<>>("regular_axis",
"An axis for real-valued data and bins of equal width."
"\nBinning is a O(1) operation.",
no_init)
@ -196,10 +196,10 @@ void register_axis_types()
(arg("self"), arg("bin"), arg("min"), arg("max"),
arg("label") = std::string(),
arg("uoflow") = true)))
.def(axis_suite<regular_axis>())
.def(axis_suite<regular_axis<>>())
;
class_<polar_axis>("polar_axis",
class_<polar_axis<>>("polar_axis",
"An axis for real-valued angles."
"\nThere are no overflow/underflow bins for this axis,"
"\nsince the axis is circular and wraps around after 2pi."
@ -208,17 +208,17 @@ void register_axis_types()
.def(init<unsigned, double, const std::string&>(
(arg("self"), arg("bin"), arg("start") = 0.0,
arg("label") = std::string())))
.def(axis_suite<polar_axis>())
.def(axis_suite<polar_axis<>>())
;
class_<variable_axis>("variable_axis",
class_<variable_axis<>>("variable_axis",
"An axis for real-valued data and bins of varying width."
"\nBinning is a O(log(N)) operation. If speed matters and"
"\nthe problem domain allows it, prefer a regular_axis.",
"\nthe problem domain allows it, prefer a regular_axis<>.",
no_init)
.def("__init__", raw_function(variable_axis_init))
.def(init<std::vector<double>, const std::string&, bool>())
.def(axis_suite<variable_axis>())
.def(axis_suite<variable_axis<>>())
;
class_<integer_axis>("integer_axis",

View File

@ -63,11 +63,11 @@ histogram_init(python::tuple args, python::dict kwargs) {
dynamic_histogram<>::axes_type axes;
for (unsigned i = 0; i < dim; ++i) {
object pa = args[i + 1];
extract<regular_axis> er(pa);
extract<regular_axis<>> er(pa);
if (er.check()) { axes.push_back(er()); continue; }
extract<polar_axis> ep(pa);
extract<polar_axis<>> ep(pa);
if (ep.check()) { axes.push_back(ep()); continue; }
extract<variable_axis> ev(pa);
extract<variable_axis<>> ev(pa);
if (ev.check()) { axes.push_back(ev()); continue; }
extract<category_axis> ec(pa);
if (ec.check()) { axes.push_back(ec()); continue; }

View File

@ -11,9 +11,9 @@ int main() {
#define SIZEOF(axis) \
std::cout << #axis << " " << sizeof(boost::histogram::axis) << std::endl
SIZEOF(regular_axis);
SIZEOF(polar_axis);
SIZEOF(variable_axis);
SIZEOF(regular_axis<>);
SIZEOF(polar_axis<>);
SIZEOF(variable_axis<>);
SIZEOF(integer_axis);
SIZEOF(category_axis);
}

View File

@ -19,21 +19,21 @@ int main() {
// bad_ctors
{
BOOST_TEST_THROWS(regular_axis(0, 0, 1), std::logic_error);
BOOST_TEST_THROWS(regular_axis(1, 1, -1), std::logic_error);
BOOST_TEST_THROWS(polar_axis(0), std::logic_error);
BOOST_TEST_THROWS(variable_axis({}), std::logic_error);
BOOST_TEST_THROWS(variable_axis({1.0}), std::logic_error);
BOOST_TEST_THROWS(regular_axis<>(0, 0, 1), std::logic_error);
BOOST_TEST_THROWS(regular_axis<>(1, 1, -1), std::logic_error);
BOOST_TEST_THROWS(polar_axis<>(0), std::logic_error);
BOOST_TEST_THROWS(variable_axis<>({}), std::logic_error);
BOOST_TEST_THROWS(variable_axis<>({1.0}), std::logic_error);
BOOST_TEST_THROWS(integer_axis(1, -1), std::logic_error);
BOOST_TEST_THROWS(category_axis({}), std::logic_error);
}
// regular_axis_operators
// regular_axis<>_operators
{
regular_axis a{4, -2, 2};
regular_axis<> a{4, -2, 2};
BOOST_TEST_EQ(a[-1], -std::numeric_limits<double>::infinity());
BOOST_TEST_EQ(a[a.bins() + 1], std::numeric_limits<double>::infinity());
regular_axis b;
regular_axis<> b;
BOOST_TEST_NOT(a == b);
b = a;
BOOST_TEST_EQ(a, b);
@ -52,12 +52,12 @@ int main() {
BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), -1);
}
// polar_axis_operators
// polar_axis<>_operators
{
using namespace boost::math::double_constants;
polar_axis a{4};
polar_axis<> a{4};
BOOST_TEST_EQ(a[-1], a[a.bins() - 1] - two_pi);
polar_axis b;
polar_axis<> b;
BOOST_TEST_NOT(a == b);
b = a;
BOOST_TEST_EQ(a, b);
@ -74,18 +74,18 @@ int main() {
BOOST_TEST_EQ(a.index(std::numeric_limits<double>::quiet_NaN()), 0);
}
// variable_axis_operators
// variable_axis<>_operators
{
variable_axis a{-1, 0, 1};
variable_axis<> a{-1, 0, 1};
BOOST_TEST_EQ(a[-1], -std::numeric_limits<double>::infinity());
BOOST_TEST_EQ(a[a.bins() + 1], std::numeric_limits<double>::infinity());
variable_axis b;
variable_axis<> b;
BOOST_TEST_NOT(a == b);
b = a;
BOOST_TEST_EQ(a, b);
b = b;
BOOST_TEST_EQ(a, b);
variable_axis c{-2, 0, 2};
variable_axis<> c{-2, 0, 2};
BOOST_TEST_NOT(a == c);
BOOST_TEST_EQ(a.index(-10.), -1);
BOOST_TEST_EQ(a.index(-1.), 0);
@ -135,9 +135,9 @@ int main() {
// axis_t_streamable
{
std::vector<axis_t> axes;
axes.push_back(regular_axis{2, -1, 1, "regular", false});
axes.push_back(polar_axis{4, 0.1, "polar"});
axes.push_back(variable_axis{{-1, 0, 1}, "variable", false});
axes.push_back(regular_axis<>{2, -1, 1, "regular", false});
axes.push_back(polar_axis<>{4, 0.1, "polar"});
axes.push_back(variable_axis<>{{-1, 0, 1}, "variable", false});
axes.push_back(category_axis{"A", "B", "C"});
axes.push_back(integer_axis{-1, 1, "integer", false});
std::ostringstream os;
@ -149,9 +149,9 @@ int main() {
// axis_t_equal_comparable
{
std::vector<axis_t> axes;
axes.push_back(regular_axis{2, -1, 1});
axes.push_back(polar_axis{4});
axes.push_back(variable_axis{-1, 0, 1});
axes.push_back(regular_axis<>{2, -1, 1});
axes.push_back(polar_axis<>{4});
axes.push_back(variable_axis<>{-1, 0, 1});
axes.push_back(category_axis{"A", "B", "C"});
axes.push_back(integer_axis{-1, 1});
for (const auto& a : axes) {

View File

@ -41,14 +41,14 @@ int main() {
auto h = dynamic_histogram<
default_axes,
adaptive_storage<>
>(regular_axis{3, -1, 1});
>(regular_axis<>{3, -1, 1});
BOOST_TEST_EQ(h.dim(), 1u);
BOOST_TEST_EQ(h.size(), 5u);
BOOST_TEST_EQ(shape(h.axis(0)), 5);
auto h2 = dynamic_histogram<
default_axes,
container_storage<std::vector<unsigned>>
>(regular_axis{3, -1, 1});
>(regular_axis<>{3, -1, 1});
BOOST_TEST(h2 == h);
}
@ -57,7 +57,7 @@ int main() {
auto h = dynamic_histogram<
default_axes,
adaptive_storage<>
>(regular_axis{3, -1, 1}, integer_axis{-1, 1});
>(regular_axis<>{3, -1, 1}, integer_axis{-1, 1});
BOOST_TEST_EQ(h.dim(), 2u);
BOOST_TEST_EQ(h.size(), 25u);
BOOST_TEST_EQ(shape(h.axis(0)), 5);
@ -65,7 +65,7 @@ int main() {
auto h2 = dynamic_histogram<
default_axes,
container_storage<std::vector<unsigned>>
>(regular_axis{3, -1, 1}, integer_axis{-1, 1});
>(regular_axis<>{3, -1, 1}, integer_axis{-1, 1});
BOOST_TEST(h2 == h);
}
@ -74,13 +74,13 @@ int main() {
auto h = dynamic_histogram<
default_axes,
adaptive_storage<>
>(regular_axis{3, -1, 1}, integer_axis{-1, 1}, polar_axis{3});
>(regular_axis<>{3, -1, 1}, integer_axis{-1, 1}, polar_axis<>{3});
BOOST_TEST_EQ(h.dim(), 3u);
BOOST_TEST_EQ(h.size(), 75u);
auto h2 = dynamic_histogram<
default_axes,
container_storage<std::vector<unsigned>>
>(regular_axis{3, -1, 1}, integer_axis{-1, 1}, polar_axis{3});
>(regular_axis<>{3, -1, 1}, integer_axis{-1, 1}, polar_axis<>{3});
BOOST_TEST(h2 == h);
}
@ -89,35 +89,35 @@ int main() {
auto h = dynamic_histogram<
default_axes,
adaptive_storage<>
>(regular_axis{3, -1, 1},
>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3},
variable_axis{-1, 0, 1});
polar_axis<>{3},
variable_axis<>{-1, 0, 1});
BOOST_TEST_EQ(h.dim(), 4u);
BOOST_TEST_EQ(h.size(), 300u);
auto h2 = dynamic_histogram<
default_axes,
container_storage<std::vector<unsigned>>
>(regular_axis{3, -1, 1},
>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3},
variable_axis{-1, 0, 1});
polar_axis<>{3},
variable_axis<>{-1, 0, 1});
BOOST_TEST(h2 == h);
}
// init_5
{
auto h = make_dynamic_histogram(regular_axis{3, -1, 1},
auto h = make_dynamic_histogram(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3},
variable_axis{-1, 0, 1},
polar_axis<>{3},
variable_axis<>{-1, 0, 1},
category_axis{"A", "B", "C"});
BOOST_TEST_EQ(h.dim(), 5u);
BOOST_TEST_EQ(h.size(), 900u);
auto h2 = make_dynamic_histogram(regular_axis{3, -1, 1},
auto h2 = make_dynamic_histogram(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3},
variable_axis{-1, 0, 1},
polar_axis<>{3},
variable_axis<>{-1, 0, 1},
category_axis{"A", "B", "C"});
BOOST_TEST(h2 == h);
}
@ -125,7 +125,7 @@ int main() {
// init_6
{
auto v = std::vector<dynamic_histogram<>::axis_type>();
v.push_back(regular_axis(100, -1, 1));
v.push_back(regular_axis<>(100, -1, 1));
v.push_back(integer_axis(1, 6));
auto h = dynamic_histogram<>(v.begin(), v.end());
BOOST_TEST_EQ(h.axis(0), v[0]);
@ -203,7 +203,7 @@ int main() {
BOOST_TEST(!(c == b));
BOOST_TEST(a == c);
BOOST_TEST(c == a);
auto d = make_dynamic_histogram(regular_axis(2, 0, 1));
auto d = make_dynamic_histogram(regular_axis<>(2, 0, 1));
BOOST_TEST(!(c == d));
BOOST_TEST(!(d == c));
c.fill(0);
@ -271,7 +271,7 @@ int main() {
// d1w
{
auto h = make_dynamic_histogram(regular_axis(2, -1, 1));
auto h = make_dynamic_histogram(regular_axis<>(2, -1, 1));
h.fill(0);
h.wfill(2, -1.0);
h.fill(-1.0);
@ -293,7 +293,7 @@ int main() {
// d2
{
auto h = make_dynamic_histogram(regular_axis(2, -1, 1),
auto h = make_dynamic_histogram(regular_axis<>(2, -1, 1),
integer_axis(-1, 1, "", false));
h.fill(-1, -1);
h.fill(-1, 0);
@ -344,7 +344,7 @@ int main() {
// d2w
{
auto h = make_dynamic_histogram(regular_axis(2, -1, 1),
auto h = make_dynamic_histogram(regular_axis<>(2, -1, 1),
integer_axis(-1, 1, "", false));
h.fill(-1, 0); // -> 0, 1
h.wfill(10, -1, -1); // -> 0, 0
@ -407,8 +407,8 @@ int main() {
// add_0
{
auto a = make_dynamic_histogram(integer_axis(-1, 1));
auto b = make_dynamic_histogram(regular_axis(3, -1, 1));
auto c = make_dynamic_histogram(regular_axis(3, -1.1, 1));
auto b = make_dynamic_histogram(regular_axis<>(3, -1, 1));
auto c = make_dynamic_histogram(regular_axis<>(3, -1.1, 1));
BOOST_TEST_THROWS(a += b, std::logic_error);
BOOST_TEST_THROWS(b += c, std::logic_error);
}
@ -420,7 +420,7 @@ int main() {
adaptive_storage<>
>(integer_axis(-1, 1));
auto b = dynamic_histogram<
mpl::vector<integer_axis, regular_axis>,
mpl::vector<integer_axis, regular_axis<>>,
container_storage<std::vector<unsigned>>
>(integer_axis(-1, 1));
a.fill(-1);
@ -517,9 +517,9 @@ int main() {
// histogram_serialization
{
auto a = make_dynamic_histogram(regular_axis(3, -1, 1, "r"),
polar_axis(4, 0.0, "p"),
variable_axis({0.1, 0.2, 0.3, 0.4, 0.5}, "v"),
auto a = make_dynamic_histogram(regular_axis<>(3, -1, 1, "r"),
polar_axis<>(4, 0.0, "p"),
variable_axis<>({0.1, 0.2, 0.3, 0.4, 0.5}, "v"),
category_axis{"A", "B", "C"},
integer_axis(0, 1, "i"));
a.fill(0.5, 0.1, 0.25, 1, 0);

View File

@ -38,7 +38,7 @@ double compare_1d(unsigned n, int distrib)
auto best = std::numeric_limits<double>::max();
for (unsigned k = 0; k < 50; ++k) {
auto h = Histogram(regular_axis(100, 0, 1));
auto h = Histogram(regular_axis<>(100, 0, 1));
auto t = clock();
for (unsigned i = 0; i < n; ++i)
h.fill(r[i]);
@ -56,9 +56,9 @@ double compare_3d(unsigned n, int distrib)
auto best = std::numeric_limits<double>::max();
for (unsigned k = 0; k < 50; ++k) {
auto h = Histogram(regular_axis(100, 0, 1),
regular_axis(100, 0, 1),
regular_axis(100, 0, 1));
auto h = Histogram(regular_axis<>(100, 0, 1),
regular_axis<>(100, 0, 1),
regular_axis<>(100, 0, 1));
auto t = clock();
for (unsigned i = 0; i < n; ++i)
h.fill(r[3 * i], r[3 * i + 1], r[3 * i + 2]);
@ -78,12 +78,12 @@ double compare_6d(unsigned n, int distrib)
for (unsigned k = 0; k < 50; ++k) {
double x[6];
auto h = Histogram(regular_axis(10, 0, 1),
regular_axis(10, 0, 1),
regular_axis(10, 0, 1),
regular_axis(10, 0, 1),
regular_axis(10, 0, 1),
regular_axis(10, 0, 1));
auto h = Histogram(regular_axis<>(10, 0, 1),
regular_axis<>(10, 0, 1),
regular_axis<>(10, 0, 1),
regular_axis<>(10, 0, 1),
regular_axis<>(10, 0, 1),
regular_axis<>(10, 0, 1));
auto t = clock();
for (unsigned i = 0; i < n; ++i) {
@ -108,7 +108,7 @@ int main() {
printf("hs_ss %.3f\n",
compare_1d<
static_histogram<
mpl::vector<regular_axis>,
mpl::vector<regular_axis<>>,
container_storage<std::vector<int>>
>
>(12000000, itype)
@ -116,7 +116,7 @@ int main() {
printf("hs_sd %.3f\n",
compare_1d<
static_histogram<
mpl::vector<regular_axis>,
mpl::vector<regular_axis<>>,
adaptive_storage<>
>
>(12000000, itype)
@ -148,7 +148,7 @@ int main() {
printf("hs_ss %.3f\n",
compare_3d<
static_histogram<
mpl::vector<regular_axis, regular_axis, regular_axis>,
mpl::vector<regular_axis<>, regular_axis<>, regular_axis<>>,
container_storage<std::vector<int>>
>
>(4000000, itype)
@ -156,7 +156,7 @@ int main() {
printf("hs_sd %.3f\n",
compare_3d<
static_histogram<
mpl::vector<regular_axis, regular_axis, regular_axis>,
mpl::vector<regular_axis<>, regular_axis<>, regular_axis<>>,
adaptive_storage<>
>
>(4000000, itype)
@ -188,8 +188,8 @@ int main() {
printf("hs_ss %.3f\n",
compare_6d<
static_histogram<
mpl::vector<regular_axis, regular_axis, regular_axis,
regular_axis, regular_axis, regular_axis>,
mpl::vector<regular_axis<>, regular_axis<>, regular_axis<>,
regular_axis<>, regular_axis<>, regular_axis<>>,
container_storage<std::vector<int>>
>
>(2000000, itype)
@ -197,8 +197,8 @@ int main() {
printf("hs_sd %.3f\n",
compare_6d<
static_histogram<
mpl::vector<regular_axis, regular_axis, regular_axis,
regular_axis, regular_axis, regular_axis>,
mpl::vector<regular_axis<>, regular_axis<>, regular_axis<>,
regular_axis<>, regular_axis<>, regular_axis<>>,
adaptive_storage<>
>
>(2000000, itype)

View File

@ -35,7 +35,7 @@ int main() {
>();
BOOST_TEST(h2 == h);
auto h3 = static_histogram<
mpl::vector<regular_axis>,
mpl::vector<regular_axis<>>,
adaptive_storage<>
>();
BOOST_TEST(!(h3 == h));
@ -43,68 +43,68 @@ int main() {
// init_1
{
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis{3, -1, 1});
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis<>{3, -1, 1});
BOOST_TEST_EQ(h.dim(), 1);
BOOST_TEST_EQ(h.size(), 5);
BOOST_TEST_EQ(shape(h.axis<0>()), 5);
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis{3, -1, 1});
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis<>{3, -1, 1});
BOOST_TEST(h2 == h);
}
// init_2
{
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis{3, -1, 1},
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1});
BOOST_TEST_EQ(h.dim(), 2);
BOOST_TEST_EQ(h.size(), 25);
BOOST_TEST_EQ(shape(h.axis<0>()), 5);
BOOST_TEST_EQ(shape(h.axis<1>()), 5);
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis{3, -1, 1},
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1});
BOOST_TEST(h2 == h);
}
// init_3
{
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis{3, -1, 1},
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3});
polar_axis<>{3});
BOOST_TEST_EQ(h.dim(), 3);
BOOST_TEST_EQ(h.size(), 75);
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis{3, -1, 1},
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3});
polar_axis<>{3});
BOOST_TEST(h2 == h);
}
// init_4
{
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis{3, -1, 1},
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3},
variable_axis{-1, 0, 1});
polar_axis<>{3},
variable_axis<>{-1, 0, 1});
BOOST_TEST_EQ(h.dim(), 4);
BOOST_TEST_EQ(h.size(), 300);
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis{3, -1, 1},
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3},
variable_axis{-1, 0, 1});
polar_axis<>{3},
variable_axis<>{-1, 0, 1});
BOOST_TEST(h2 == h);
}
// init_5
{
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis{3, -1, 1},
auto h = make_static_histogram_with<adaptive_storage<>>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3},
variable_axis{-1, 0, 1},
polar_axis<>{3},
variable_axis<>{-1, 0, 1},
category_axis{"A", "B", "C"});
BOOST_TEST_EQ(h.dim(), 5);
BOOST_TEST_EQ(h.size(), 900);
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis{3, -1, 1},
auto h2 = make_static_histogram_with<container_storage<std::vector<unsigned>>>(regular_axis<>{3, -1, 1},
integer_axis{-1, 1},
polar_axis{3},
variable_axis{-1, 0, 1},
polar_axis<>{3},
variable_axis<>{-1, 0, 1},
category_axis{"A", "B", "C"});
BOOST_TEST(h2 == h);
}
@ -173,7 +173,7 @@ int main() {
BOOST_TEST(!(c == b));
BOOST_TEST(a == c);
BOOST_TEST(c == a);
auto d = make_static_histogram(regular_axis(2, 0, 1));
auto d = make_static_histogram(regular_axis<>(2, 0, 1));
BOOST_TEST(!(c == d));
BOOST_TEST(!(d == c));
c.fill(0);
@ -241,7 +241,7 @@ int main() {
// d1w
{
auto h = make_static_histogram(regular_axis(2, -1, 1));
auto h = make_static_histogram(regular_axis<>(2, -1, 1));
h.fill(0);
h.wfill(2.0, -1.0);
h.fill(-1.0);
@ -263,7 +263,7 @@ int main() {
// d2
{
auto h = make_static_histogram(regular_axis(2, -1, 1),
auto h = make_static_histogram(regular_axis<>(2, -1, 1),
integer_axis(-1, 1, "", false));
h.fill(-1, -1);
h.fill(-1, 0);
@ -314,7 +314,7 @@ int main() {
// d2w
{
auto h = make_static_histogram(regular_axis(2, -1, 1),
auto h = make_static_histogram(regular_axis<>(2, -1, 1),
integer_axis(-1, 1, "", false));
h.fill(-1, 0); // -> 0, 1
h.wfill(10, -1, -1); // -> 0, 0
@ -475,7 +475,7 @@ int main() {
namespace bh = boost::histogram;
// create 1d-histogram with 10 equidistant bins from -1.0 to 2.0,
// with axis of histogram labeled as "x"
auto h = bh::make_static_histogram(bh::regular_axis(10, -1.0, 2.0, "x"));
auto h = bh::make_static_histogram(bh::regular_axis<>(10, -1.0, 2.0, "x"));
// fill histogram with data
h.fill(-1.5); // put in underflow bin
@ -517,9 +517,9 @@ int main() {
// histogram_serialization
{
auto a = make_static_histogram(regular_axis(3, -1, 1, "r"),
polar_axis(4, 0.0, "p"),
variable_axis({0.1, 0.2, 0.3, 0.4, 0.5}, "v"),
auto a = make_static_histogram(regular_axis<>(3, -1, 1, "r"),
polar_axis<>(4, 0.0, "p"),
variable_axis<>({0.1, 0.2, 0.3, 0.4, 0.5}, "v"),
category_axis{"A", "B", "C"},
integer_axis(0, 1, "i"));
a.fill(0.5, 0.1, 0.25, 1, 0);