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