mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-09 23:04:07 +00:00
asserts on dimension of input
This commit is contained in:
parent
8e792c60dc
commit
c4cf612a13
@ -1,6 +1,7 @@
|
||||
#include <boost/histogram/nhistogram.hpp>
|
||||
#include <boost/histogram/axis.hpp>
|
||||
#include <boost/random.hpp>
|
||||
#include <boost/array.hpp>
|
||||
|
||||
#include <TH1I.h>
|
||||
#include <TH3I.h>
|
||||
@ -50,7 +51,7 @@ void compare_1d(unsigned n)
|
||||
t = clock() - t;
|
||||
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
||||
|
||||
nhistogram h(regular_axis(100, 0, 1, std::string(), true));
|
||||
nhistogram h(regular_axis(100, 0, 1));
|
||||
t = clock();
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
h.fill(r[i]);
|
||||
@ -79,9 +80,9 @@ void compare_3d(unsigned n)
|
||||
t = clock() - t;
|
||||
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
||||
|
||||
nhistogram h(regular_axis(100, 0, 1, "", true),
|
||||
regular_axis(100, 0, 1, "", true),
|
||||
regular_axis(100, 0, 1, "", true));
|
||||
nhistogram h(regular_axis(100, 0, 1),
|
||||
regular_axis(100, 0, 1),
|
||||
regular_axis(100, 0, 1));
|
||||
t = clock();
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
h.fill(r[3 * i], r[3 * i + 1], r[3 * i + 2]);
|
||||
@ -123,12 +124,13 @@ void compare_6d(unsigned n)
|
||||
regular_axis(10, 0, 1),
|
||||
regular_axis(10, 0, 1),
|
||||
regular_axis(10, 0, 1));
|
||||
boost::array<double, 6> y;
|
||||
|
||||
t = clock();
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
for (unsigned k = 0; k < 6; ++k)
|
||||
x[k] = r[6 * i + k];
|
||||
h.fill(x);
|
||||
y[k] = r[6 * i + k];
|
||||
h.fill(y);
|
||||
}
|
||||
t = clock() - t;
|
||||
best_boost = std::min(best_boost, double(t) / CLOCKS_PER_SEC);
|
||||
@ -141,6 +143,6 @@ void compare_6d(unsigned n)
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
compare_1d(1000000);
|
||||
compare_3d(100000);
|
||||
compare_3d(500000);
|
||||
compare_6d(100000);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
namespace boost {
|
||||
namespace histogram {
|
||||
|
||||
// common base class for most axes
|
||||
class axis_base {
|
||||
public:
|
||||
inline unsigned bins() const { return size_ > 0 ? size_ : -size_; }
|
||||
@ -26,7 +27,7 @@ protected:
|
||||
axis_base(int, const std::string&, bool);
|
||||
|
||||
axis_base() : size_(0) {}
|
||||
explicit axis_base(const axis_base&);
|
||||
axis_base(const axis_base&);
|
||||
axis_base& operator=(const axis_base&);
|
||||
|
||||
bool operator==(const axis_base&) const;
|
||||
@ -45,6 +46,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
// mixin for real-valued axes
|
||||
template <typename Derived>
|
||||
class real_axis {
|
||||
public:
|
||||
@ -71,7 +73,7 @@ public:
|
||||
bool uoflow = true);
|
||||
|
||||
regular_axis() {}
|
||||
explicit regular_axis(const regular_axis&);
|
||||
regular_axis(const regular_axis&);
|
||||
regular_axis& operator=(const regular_axis&);
|
||||
|
||||
inline int index(double x) const {
|
||||
@ -98,11 +100,12 @@ private:
|
||||
// real polar axis (constant bin widths, wraps around)
|
||||
class polar_axis: public axis_base, public real_axis<polar_axis> {
|
||||
public:
|
||||
explicit
|
||||
polar_axis(unsigned n, double start = 0.0,
|
||||
const std::string& label = std::string());
|
||||
|
||||
polar_axis() {}
|
||||
explicit polar_axis(const polar_axis&);
|
||||
polar_axis(const polar_axis&);
|
||||
polar_axis& operator=(const polar_axis&);
|
||||
|
||||
inline int index(double x) const {
|
||||
@ -130,6 +133,7 @@ private:
|
||||
class variable_axis : public axis_base, public real_axis<variable_axis> {
|
||||
public:
|
||||
template <typename Container>
|
||||
explicit
|
||||
variable_axis(const Container& x,
|
||||
const std::string& label = std::string(),
|
||||
bool uoflow = true) :
|
||||
@ -152,7 +156,7 @@ public:
|
||||
}
|
||||
|
||||
variable_axis() {}
|
||||
explicit variable_axis(const variable_axis&);
|
||||
variable_axis(const variable_axis&);
|
||||
variable_axis& operator=(const variable_axis&);
|
||||
|
||||
inline int index(double x) const {
|
||||
@ -180,11 +184,13 @@ class category_axis {
|
||||
public:
|
||||
typedef std::string value_type;
|
||||
|
||||
explicit
|
||||
category_axis(const std::string&);
|
||||
explicit
|
||||
category_axis(const std::vector<std::string>&);
|
||||
|
||||
category_axis() {}
|
||||
explicit category_axis(const category_axis&);
|
||||
category_axis(const category_axis&);
|
||||
category_axis& operator=(const category_axis&);
|
||||
|
||||
inline unsigned bins() const { return categories_.size(); }
|
||||
@ -213,7 +219,7 @@ public:
|
||||
bool uoflow = true);
|
||||
|
||||
integer_axis() {}
|
||||
explicit integer_axis(const integer_axis&);
|
||||
integer_axis(const integer_axis&);
|
||||
integer_axis& operator=(const integer_axis&);
|
||||
|
||||
inline int index(double x) const
|
||||
|
@ -44,11 +44,8 @@ public:
|
||||
|
||||
protected:
|
||||
histogram_base() {}
|
||||
|
||||
explicit histogram_base(const axes_type& axes);
|
||||
|
||||
explicit histogram_base(const axis_type& a) : axes_(1, a) { update_buffers(); }
|
||||
|
||||
#define BOOST_HISTOGRAM_BASE_APPEND(z, n, unused) axes_.push_back(a ## n);
|
||||
#define BOOST_HISTOGRAM_BASE_CTOR(z, n, unused) \
|
||||
histogram_base( BOOST_PP_ENUM_PARAMS_Z(z, n, const axis_type& a) ) \
|
||||
@ -59,7 +56,7 @@ protected:
|
||||
}
|
||||
|
||||
// generates constructors taking 2 to AXIS_LIMIT arguments
|
||||
BOOST_PP_REPEAT_FROM_TO(2, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_BASE_CTOR, nil)
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_BASE_CTOR, nil)
|
||||
|
||||
bool operator==(const histogram_base&) const;
|
||||
bool operator!=(const histogram_base& o) const
|
||||
@ -68,7 +65,7 @@ BOOST_PP_REPEAT_FROM_TO(2, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_BASE_CTOR
|
||||
template <typename Array>
|
||||
inline
|
||||
size_type pos(const Array& v) const {
|
||||
int32_t idx[BOOST_HISTOGRAM_AXIS_LIMIT];
|
||||
int idx[BOOST_HISTOGRAM_AXIS_LIMIT];
|
||||
for (unsigned i = 0, n = axes_.size(); i < n; ++i)
|
||||
idx[i] = apply_visitor(detail::index_visitor(v[i]), axes_[i]);
|
||||
return linearize(idx);
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <boost/serialization/access.hpp>
|
||||
#include <boost/serialization/base_object.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/concept/requires.hpp>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
@ -18,15 +20,14 @@ class nhistogram : public histogram_base {
|
||||
public:
|
||||
nhistogram() {}
|
||||
|
||||
explicit
|
||||
nhistogram(const axes_type& axes) :
|
||||
histogram_base(axes),
|
||||
data_(field_count())
|
||||
nhistogram(const nhistogram& o) :
|
||||
histogram_base(o),
|
||||
data_(o.data_)
|
||||
{}
|
||||
|
||||
explicit
|
||||
nhistogram(const axis_type& a) :
|
||||
histogram_base(a),
|
||||
nhistogram(const axes_type& axes) :
|
||||
histogram_base(axes),
|
||||
data_(field_count())
|
||||
{}
|
||||
|
||||
@ -36,47 +37,69 @@ public:
|
||||
data_(field_count()) \
|
||||
{}
|
||||
|
||||
// generates constructors taking 2 to AXIS_LIMIT arguments
|
||||
BOOST_PP_REPEAT_FROM_TO(2, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_CTOR, nil)
|
||||
// generates constructors taking 1 to AXIS_LIMIT arguments
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_CTOR, nil)
|
||||
|
||||
double sum() const;
|
||||
|
||||
template <typename Array>
|
||||
template <typename T>
|
||||
inline
|
||||
void fill(const Array& v)
|
||||
void fill(const T& v)
|
||||
{
|
||||
BOOST_ASSERT(v.size() == dim());
|
||||
const size_type k = pos(v);
|
||||
if (k != uintmax_t(-1))
|
||||
data_.increase(k);
|
||||
}
|
||||
|
||||
void fill(double x,
|
||||
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PP_DEC(BOOST_HISTOGRAM_AXIS_LIMIT),
|
||||
double x, 0.0))
|
||||
// C-style call
|
||||
inline
|
||||
void fill(unsigned n, const double* v)
|
||||
{
|
||||
const double buffer[BOOST_HISTOGRAM_AXIS_LIMIT] = {
|
||||
x, BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_HISTOGRAM_AXIS_LIMIT), x)
|
||||
};
|
||||
fill(buffer);
|
||||
BOOST_ASSERT(n == dim());
|
||||
const size_type k = pos(v);
|
||||
if (k != uintmax_t(-1))
|
||||
data_.increase(k);
|
||||
}
|
||||
|
||||
#define BOOST_NHISTOGRAM_FILL(z, n, unused) \
|
||||
inline \
|
||||
void fill( BOOST_PP_ENUM_PARAMS_Z(z, n, double x) ) \
|
||||
{ \
|
||||
const double buffer[n] = { BOOST_PP_ENUM_PARAMS(n, x) }; \
|
||||
fill(n, buffer); /* size is checked here */ \
|
||||
}
|
||||
|
||||
// generates fill functions taking 1 to AXIS_LIMT arguments
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_FILL, nil)
|
||||
|
||||
template <typename Array>
|
||||
inline
|
||||
size_type operator()(const Array& idx)
|
||||
const
|
||||
{ return data_.read(linearize(idx)); }
|
||||
|
||||
size_type operator()(int i,
|
||||
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_PP_DEC(BOOST_HISTOGRAM_AXIS_LIMIT),
|
||||
int i, 0))
|
||||
double value(const Array& idx)
|
||||
const
|
||||
{
|
||||
const int32_t idx[BOOST_HISTOGRAM_AXIS_LIMIT] = {
|
||||
i, BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_HISTOGRAM_AXIS_LIMIT), i)
|
||||
};
|
||||
return operator()(idx);
|
||||
BOOST_ASSERT(idx.size() == dim());
|
||||
return data_.read(linearize(idx));
|
||||
}
|
||||
|
||||
// C-style call
|
||||
double value(unsigned n, const int* idx)
|
||||
const
|
||||
{
|
||||
BOOST_ASSERT(n == dim());
|
||||
return data_.read(linearize(idx));
|
||||
}
|
||||
|
||||
#define BOOST_NHISTOGRAM_VALUE(z, n, unused) \
|
||||
double value( BOOST_PP_ENUM_PARAMS_Z(z, n, int i) ) \
|
||||
const \
|
||||
{ \
|
||||
const int idx[n] = { BOOST_PP_ENUM_PARAMS_Z(z, n, i) }; \
|
||||
return value(n, idx); /* size is checked here */ \
|
||||
}
|
||||
|
||||
// generates value functions taking 1 to AXIS_LIMT arguments
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_VALUE, nil)
|
||||
|
||||
bool operator==(const nhistogram& o) const
|
||||
{ return histogram_base::operator==(o) &&
|
||||
data_ == o.data_; }
|
||||
|
@ -104,7 +104,7 @@ nhistogram_fill(python::tuple args, python::dict kwargs) {
|
||||
|
||||
for (unsigned i = 0; i < dims[0]; ++i) {
|
||||
double* v = (double*)PyArray_GETPTR1(a, i);
|
||||
self.fill(v);
|
||||
self.fill(self.dim(), v);
|
||||
}
|
||||
|
||||
Py_DECREF(a);
|
||||
@ -127,7 +127,7 @@ nhistogram_fill(python::tuple args, python::dict kwargs) {
|
||||
double v[BOOST_HISTOGRAM_AXIS_LIMIT];
|
||||
for (unsigned i = 0; i < dim; ++i)
|
||||
v[i] = extract<double>(args[1 + i]);
|
||||
self.fill(v);
|
||||
self.fill(self.dim(), v);
|
||||
return object();
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ nhistogram_getitem(const nhistogram& self, python::object oidx) {
|
||||
using namespace python;
|
||||
|
||||
if (self.dim() == 1)
|
||||
return self(extract<int>(oidx)());
|
||||
return self.value(extract<int>(oidx)());
|
||||
|
||||
const unsigned dim = len(oidx);
|
||||
if (dim != self.dim()) {
|
||||
@ -153,7 +153,7 @@ nhistogram_getitem(const nhistogram& self, python::object oidx) {
|
||||
for (unsigned i = 0; i < dim; ++i)
|
||||
idx[i] = extract<int>(oidx[i]);
|
||||
|
||||
return self(idx);
|
||||
return self.value(self.dim(), idx);
|
||||
}
|
||||
|
||||
void register_nhistogram()
|
||||
|
Loading…
x
Reference in New Issue
Block a user