several bug-fixes, more tests for new weight-filling

This commit is contained in:
Hans Dembinski 2016-04-09 22:36:53 -04:00
parent fbea37a0af
commit 492d73f18f
7 changed files with 400 additions and 119 deletions

View File

@ -1,7 +1,9 @@
#include <cstdio>
#include <boost/preprocessor.hpp>
#include <boost/histogram/axis.hpp>
#include <boost/histogram/detail/wtype.hpp>
#include <boost/container/vector.hpp>
#include <boost/container/static_vector.hpp>
#include <boost/scoped_array.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <vector>
@ -17,6 +19,7 @@ int main(int argc, char** argv) {
SIZEOF(float);
SIZEOF(double);
SIZEOF(void*);
SIZEOF(detail::wtype);
SIZEOF(boost::multiprecision::int128_t);
SIZEOF(boost::multiprecision::int512_t);
SIZEOF(boost::multiprecision::cpp_int);
@ -24,6 +27,8 @@ int main(int argc, char** argv) {
SIZEOF(std::vector<double>);
SIZEOF(std::valarray<double>);
SIZEOF(boost::container::vector<double>);
typedef boost::container::static_vector<axis_type,16> static_vector_a16;
SIZEOF(static_vector_a16);
SIZEOF(boost::scoped_array<double>);
SIZEOF(regular_axis);
SIZEOF(polar_axis);

View File

@ -124,13 +124,12 @@ void compare_6d(unsigned n)
regular_axis(10, 0, 1),
regular_axis(10, 0, 1),
regular_axis(10, 0, 1));
double y[6];
t = clock();
for (unsigned i = 0; i < n; ++i) {
for (unsigned k = 0; k < 6; ++k)
y[k] = r[6 * i + k];
h.fill(6, y);
x[k] = r[6 * i + k];
h.fill_c(6, x);
}
t = clock() - t;
best_boost = std::min(best_boost, double(t) / CLOCKS_PER_SEC);

View File

@ -49,12 +49,13 @@ public:
BOOST_HISTOGRAM_NSTORE_INC(uint32_t);
BOOST_HISTOGRAM_NSTORE_INC(uint64_t);
#undef BOOST_HISTOGRAM_NSTORE_INC
default: assert(!"invalid depth");
default: BOOST_ASSERT(!"invalid depth");
}
}
inline void increase(size_type i, double w) {
assert(depth_ == sizeof(wtype));
if (depth_ != sizeof(wtype))
wconvert();
((wtype*)buffer_)[i] += w;
}
@ -84,7 +85,7 @@ private:
BOOST_HISTOGRAM_NSTORE_CASE(uint32_t);
BOOST_HISTOGRAM_NSTORE_CASE(uint64_t);
#undef BOOST_HISTOGRAM_NSTORE_CASE
default: assert(!"invalid depth");
default: BOOST_ASSERT(!"invalid depth");
}
return 0;
}
@ -127,7 +128,7 @@ private:
BOOST_HISTOGRAM_NSTORE_SAVE(uint64_t);
BOOST_HISTOGRAM_NSTORE_SAVE(wtype);
#undef BOOST_HISTOGRAM_NSTORE_SAVE
default: assert(!"invalid depth");
default: BOOST_ASSERT(!"invalid depth");
}
}
@ -150,7 +151,7 @@ private:
BOOST_HISTOGRAM_NSTORE_LOAD(uint64_t);
BOOST_HISTOGRAM_NSTORE_LOAD(wtype);
#undef BOOST_HISTOGRAM_NSTORE_LOAD
default: assert(!"invalid depth");
default: BOOST_ASSERT(!"invalid depth");
}
}
}

View File

@ -11,6 +11,7 @@
#include <boost/type_traits.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/assert.hpp>
#include <stdexcept>
namespace boost {
namespace histogram {
@ -30,22 +31,11 @@ public:
// generates constructors taking 1 to AXIS_LIMIT arguments
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_CTOR, nil)
// template <typename C>
// inline
// void
// fill(const C& v)
// {
// BOOST_ASSERT(v.size() == dim());
// const size_type k = pos(v);
// if (k != uintmax_t(-1))
// data_.increase(k);
// }
// C-style call
inline
void fill(unsigned n, const double* v)
void fill_c(unsigned n, const double* v)
{
BOOST_ASSERT(n == dim());
BOOST_ASSERT_MSG(n == dim(), "wrong number of arguments");
const size_type k = pos(v);
if (k != uintmax_t(-1))
data_.increase(k);
@ -56,27 +46,17 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_CTOR, nil
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 */ \
fill_c(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_HISTOGRAM_FILL, nil)
// template <typename Container>
// inline
// void wfill(const Container& v, double w)
// {
// BOOST_ASSERT(v.size() == dim());
// const size_type k = pos(v);
// if (k != uintmax_t(-1))
// data_.increase(k, w);
// }
// C-style call
inline
void wfill(unsigned n, const double* v, double w)
void wfill_c(unsigned n, const double* v, double w)
{
BOOST_ASSERT(n == dim());
BOOST_ASSERT_MSG(n == dim(), "wrong number of arguments");
const size_type k = pos(v);
if (k != uintmax_t(-1))
data_.increase(k, w);
@ -87,27 +67,18 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_FILL, nil
void wfill( BOOST_PP_ENUM_PARAMS_Z(z, n, double x), double w ) \
{ \
const double buffer[n] = { BOOST_PP_ENUM_PARAMS(n, x) }; \
wfill(n, buffer, w); /* size is checked here */ \
wfill_c(n, buffer, w); /* size is checked here */ \
}
// generates wfill functions taking 1 to AXIS_LIMT arguments
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_WFILL, nil)
// template <typename Container>
// inline
// double value(const Container& idx)
// const
// {
// BOOST_ASSERT(idx.size() == dim());
// return data_.value(linearize(idx));
// }
// C-style call
inline
double value(unsigned n, const int* idx)
double value_c(unsigned n, const int* idx)
const
{
BOOST_ASSERT(n == dim());
BOOST_ASSERT_MSG(n == dim(), "wrong number of arguments");
return data_.value(linearize(idx));
}
@ -117,27 +88,18 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_WFILL, ni
const \
{ \
const int idx[n] = { BOOST_PP_ENUM_PARAMS_Z(z, n, i) }; \
return value(n, idx); /* size is checked here */ \
return value_c(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_HISTOGRAM_VALUE, nil)
// template <typename Container>
// inline
// double variance(const Container& idx)
// const
// {
// BOOST_ASSERT(idx.size() == dim());
// return data_.variance(linearize(idx));
// }
// C-style call
inline
double variance(unsigned n, const int* idx)
double variance_c(unsigned n, const int* idx)
const
{
BOOST_ASSERT(n == dim());
BOOST_ASSERT_MSG(n == dim(), "wrong number of arguments");
return data_.variance(linearize(idx));
}
@ -147,7 +109,7 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_VALUE, ni
const \
{ \
const int idx[n] = { BOOST_PP_ENUM_PARAMS_Z(z, n, i) }; \
return variance(n, idx); /* size is checked here */ \
return variance_c(n, idx); /* size is checked here */ \
}
// generates variance functions taking 1 to AXIS_LIMT arguments
@ -162,7 +124,12 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_VARIANCE,
data_ == o.data_; }
histogram& operator+=(const histogram& o)
{ data_ += o.data_; return *this; }
{
if (!histogram_base::operator==(o))
throw std::logic_error("histograms have different axes");
data_ += o.data_;
return *this;
}
private:
detail::nstore data_;

View File

@ -24,8 +24,8 @@ histogram_init(python::tuple args, python::dict kwargs) {
object pyinit = self.attr("__init__");
if (kwargs) {
PyErr_SetString(PyExc_TypeError, "no keyword arguments allowed");
throw_error_already_set();
PyErr_SetString(PyExc_RuntimeError, "no keyword arguments allowed");
throw_error_already_set();
}
// normal constructor
@ -55,6 +55,10 @@ histogram_fill(python::tuple args, python::dict kwargs) {
const unsigned nargs = len(args);
histogram& self = extract<histogram&>(args[0]);
object ow;
if (kwargs)
ow = kwargs["w"];
#ifdef USE_NUMPY
if (nargs == 2) {
object o = args[1];
@ -86,9 +90,40 @@ histogram_fill(python::tuple args, python::dict kwargs) {
throw_error_already_set();
}
for (unsigned i = 0; i < dims[0]; ++i) {
double* v = (double*)PyArray_GETPTR1(a, i);
self.fill(self.dim(), v);
PyArrayObject* aw = 0;
if (!ow.is_none()) {
if (PySequence_Check(ow.ptr())) {
PyArrayObject* aw = (PyArrayObject*)
PyArray_FROM_OTF(ow.ptr(), NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
if (!aw) {
PyErr_SetString(PyExc_ValueError, "could not convert sequence into array");
throw_error_already_set();
}
if (PyArray_NDIM(aw) != 1) {
PyErr_SetString(PyExc_ValueError, "array has to be one-dimensional");
throw_error_already_set();
}
if (PyArray_DIMS(aw)[0] != dims[0]) {
PyErr_SetString(PyExc_ValueError, "sizes do not match");
throw_error_already_set();
}
}
}
if (aw) {
for (unsigned i = 0; i < dims[0]; ++i) {
double* v = (double*)PyArray_GETPTR1(a, i);
double* w = (double*)PyArray_GETPTR1(aw, i);
self.wfill_c(self.dim(), v, *w);
}
Py_DECREF(aw);
} else {
for (unsigned i = 0; i < dims[0]; ++i) {
double* v = (double*)PyArray_GETPTR1(a, i);
self.fill_c(self.dim(), v);
}
}
Py_DECREF(a);
@ -99,40 +134,66 @@ histogram_fill(python::tuple args, python::dict kwargs) {
const unsigned dim = nargs - 1;
if (dim != self.dim()) {
PyErr_SetString(PyExc_TypeError, "wrong number of arguments");
PyErr_SetString(PyExc_RuntimeError, "wrong number of arguments");
throw_error_already_set();
}
if (kwargs) {
PyErr_SetString(PyExc_TypeError, "no keyword arguments allowed");
throw_error_already_set();
}
double v[BOOST_HISTOGRAM_AXIS_LIMIT];
for (unsigned i = 0; i < dim; ++i)
v[i] = extract<double>(args[1 + i]);
self.fill(self.dim(), v);
if (ow.is_none()) {
self.fill_c(self.dim(), v);
} else {
const double w = extract<double>(ow);
self.wfill_c(self.dim(), v, w);
}
return object();
}
uint64_t
histogram_getitem(const histogram& self, python::object oidx) {
python::object
histogram_value(python::tuple args, python::dict kwargs) {
using namespace python;
const histogram& self = extract<const histogram&>(args[0]);
if (self.dim() == 1)
return self.value(extract<int>(oidx)());
const unsigned dim = len(oidx);
if (dim != self.dim()) {
if (self.dim() != (len(args) - 1)) {
PyErr_SetString(PyExc_RuntimeError, "wrong number of arguments");
throw_error_already_set();
}
int idx[BOOST_HISTOGRAM_AXIS_LIMIT];
for (unsigned i = 0; i < dim; ++i)
idx[i] = extract<int>(oidx[i]);
if (kwargs) {
PyErr_SetString(PyExc_ValueError, "no keyword arguments allowed");
throw_error_already_set();
}
return self.value(self.dim(), idx);
int idx[BOOST_HISTOGRAM_AXIS_LIMIT];
for (unsigned i = 0; i < self.dim(); ++i)
idx[i] = extract<int>(args[1 + i]);
return object(self.value_c(self.dim(), idx));
}
python::object
histogram_variance(python::tuple args, python::dict kwargs) {
using namespace python;
const histogram& self = extract<const histogram&>(args[0]);
if (self.dim() != (len(args) - 1)) {
PyErr_SetString(PyExc_RuntimeError, "wrong number of arguments");
throw_error_already_set();
}
if (kwargs) {
PyErr_SetString(PyExc_RuntimeError, "no keyword arguments allowed");
throw_error_already_set();
}
int idx[BOOST_HISTOGRAM_AXIS_LIMIT];
for (unsigned i = 0; i < self.dim(); ++i)
idx[i] = extract<int>(args[1 + i]);
return object(self.variance_c(self.dim(), idx));
}
class histogram_access {
@ -140,12 +201,17 @@ public:
static
python::dict
histogram_array_interface(histogram& self) {
python::dict d;
python::list shape;
for (unsigned i = 0; i < self.dim(); ++i)
shape.append(self.shape(i));
python::dict d;
if (self.data_.depth() == sizeof(detail::wtype)) {
shape.append(2);
d["typestr"] = python::str("<f") + python::str(sizeof(double));
} else {
d["typestr"] = python::str("<u") + python::str(self.data_.depth());
}
d["shape"] = python::tuple(shape);
d["typestr"] = python::str("<u") + python::str(self.data_.depth());
d["data"] = python::make_tuple((long long)(self.data_.buffer()), false);
return d;
}
@ -166,7 +232,8 @@ void register_histogram()
.def("fill", raw_function(histogram_fill))
.add_property("depth", &histogram::depth)
.add_property("sum", &histogram::sum)
.def("__getitem__", histogram_getitem)
.def("value", raw_function(histogram_value))
.def("variance", raw_function(histogram_variance))
.def(self == self)
.def(self += self)
.def(self + self)

View File

@ -74,8 +74,147 @@ BOOST_AUTO_TEST_CASE(init_15)
regular_axis(1, -1, 1));
}
BOOST_AUTO_TEST_CASE(fill_1)
BOOST_AUTO_TEST_CASE(d1)
{
histogram h(regular_axis(3, -1, 1));
h.fill(1);
histogram h(regular_axis(2, -1, 1));
h.fill(-1);
h.fill(-1.0);
h.fill(-2.0);
h.fill(10.0);
BOOST_CHECK_EQUAL(h.sum(), 4);
BOOST_CHECK_EQUAL(h.value(-1), 1.0);
BOOST_CHECK_EQUAL(h.value(0), 2.0);
BOOST_CHECK_EQUAL(h.value(1), 0.0);
BOOST_CHECK_EQUAL(h.value(2), 1.0);
BOOST_CHECK_EQUAL(h.variance(-1), 1.0);
BOOST_CHECK_EQUAL(h.variance(0), 2.0);
BOOST_CHECK_EQUAL(h.variance(1), 0.0);
BOOST_CHECK_EQUAL(h.variance(2), 1.0);
}
BOOST_AUTO_TEST_CASE(d2)
{
histogram h(regular_axis(2, -1, 1),
integer_axis(-1, 1, std::string(), false));
h.fill(-1, -1);
h.fill(-1, 0);
h.fill(-1, -10);
h.fill(-10, 0);
BOOST_CHECK_EQUAL(h.sum(), 3);
BOOST_CHECK_EQUAL(h.value(-1, 0), 0.0);
BOOST_CHECK_EQUAL(h.value(-1, 1), 1.0);
BOOST_CHECK_EQUAL(h.value(-1, 2), 0.0);
BOOST_CHECK_EQUAL(h.value(0, 0), 1.0);
BOOST_CHECK_EQUAL(h.value(0, 1), 1.0);
BOOST_CHECK_EQUAL(h.value(0, 2), 0.0);
BOOST_CHECK_EQUAL(h.value(1, 0), 0.0);
BOOST_CHECK_EQUAL(h.value(1, 1), 0.0);
BOOST_CHECK_EQUAL(h.value(1, 2), 0.0);
BOOST_CHECK_EQUAL(h.value(2, 0), 0.0);
BOOST_CHECK_EQUAL(h.value(2, 1), 0.0);
BOOST_CHECK_EQUAL(h.value(2, 2), 0.0);
BOOST_CHECK_EQUAL(h.variance(-1, 0), 0.0);
BOOST_CHECK_EQUAL(h.variance(-1, 1), 1.0);
BOOST_CHECK_EQUAL(h.variance(-1, 2), 0.0);
BOOST_CHECK_EQUAL(h.variance(0, 0), 1.0);
BOOST_CHECK_EQUAL(h.variance(0, 1), 1.0);
BOOST_CHECK_EQUAL(h.variance(0, 2), 0.0);
BOOST_CHECK_EQUAL(h.variance(1, 0), 0.0);
BOOST_CHECK_EQUAL(h.variance(1, 1), 0.0);
BOOST_CHECK_EQUAL(h.variance(1, 2), 0.0);
BOOST_CHECK_EQUAL(h.variance(2, 0), 0.0);
BOOST_CHECK_EQUAL(h.variance(2, 1), 0.0);
BOOST_CHECK_EQUAL(h.variance(2, 2), 0.0);
}
BOOST_AUTO_TEST_CASE(d2w)
{
histogram h(regular_axis(2, -1, 1),
integer_axis(-1, 1, std::string(), false));
h.fill(-1, 0); // -> 0, 1
h.wfill(-1, -1, 10); // -> 0, 0
h.wfill(-1, -10, 5); // is ignored
h.wfill(-10, 0, 7); // -> -1, 1
BOOST_CHECK_EQUAL(h.sum(), 18);
BOOST_CHECK_EQUAL(h.value(-1, 0), 0.0);
BOOST_CHECK_EQUAL(h.value(-1, 1), 7.0);
BOOST_CHECK_EQUAL(h.value(-1, 2), 0.0);
BOOST_CHECK_EQUAL(h.value(0, 0), 10.0);
BOOST_CHECK_EQUAL(h.value(0, 1), 1.0);
BOOST_CHECK_EQUAL(h.value(0, 2), 0.0);
BOOST_CHECK_EQUAL(h.value(1, 0), 0.0);
BOOST_CHECK_EQUAL(h.value(1, 1), 0.0);
BOOST_CHECK_EQUAL(h.value(1, 2), 0.0);
BOOST_CHECK_EQUAL(h.value(2, 0), 0.0);
BOOST_CHECK_EQUAL(h.value(2, 1), 0.0);
BOOST_CHECK_EQUAL(h.value(2, 2), 0.0);
BOOST_CHECK_EQUAL(h.variance(-1, 0), 0.0);
BOOST_CHECK_EQUAL(h.variance(-1, 1), 49.0);
BOOST_CHECK_EQUAL(h.variance(-1, 2), 0.0);
BOOST_CHECK_EQUAL(h.variance(0, 0), 100.0);
BOOST_CHECK_EQUAL(h.variance(0, 1), 1.0);
BOOST_CHECK_EQUAL(h.variance(0, 2), 0.0);
BOOST_CHECK_EQUAL(h.variance(1, 0), 0.0);
BOOST_CHECK_EQUAL(h.variance(1, 1), 0.0);
BOOST_CHECK_EQUAL(h.variance(1, 2), 0.0);
BOOST_CHECK_EQUAL(h.variance(2, 0), 0.0);
BOOST_CHECK_EQUAL(h.variance(2, 1), 0.0);
BOOST_CHECK_EQUAL(h.variance(2, 2), 0.0);
}
BOOST_AUTO_TEST_CASE(add_0)
{
histogram a(integer_axis(-1, 1));
histogram b(regular_axis(3, -1, 1));
BOOST_CHECK_THROW(a + b, std::logic_error);
}
BOOST_AUTO_TEST_CASE(add_1)
{
histogram a(integer_axis(-1, 1));
histogram b(integer_axis(-1, 1));
a.fill(0);
b.fill(-1);
histogram c = a + b;
BOOST_CHECK_EQUAL(c.value(-1), 0);
BOOST_CHECK_EQUAL(c.value(0), 1);
BOOST_CHECK_EQUAL(c.value(1), 1);
BOOST_CHECK_EQUAL(c.value(2), 0);
BOOST_CHECK_EQUAL(c.value(3), 0);
}
BOOST_AUTO_TEST_CASE(add_2)
{
histogram a(integer_axis(-1, 1));
histogram b(integer_axis(-1, 1));
a.fill(0);
b.wfill(-1, 3);
histogram c = a + b;
BOOST_CHECK_EQUAL(c.value(-1), 0);
BOOST_CHECK_EQUAL(c.value(0), 3);
BOOST_CHECK_EQUAL(c.value(1), 1);
BOOST_CHECK_EQUAL(c.value(2), 0);
BOOST_CHECK_EQUAL(c.value(3), 0);
}

View File

@ -315,7 +315,7 @@ class histogram_test(unittest.TestCase):
histogram(regular_axis())
with self.assertRaises(TypeError):
histogram([integer_axis(-1, 1)])
with self.assertRaises(TypeError):
with self.assertRaises(RuntimeError):
histogram(integer_axis(-1, 1), unknown_keyword="nh")
h = histogram(integer_axis(-1, 1))
@ -353,14 +353,14 @@ class histogram_test(unittest.TestCase):
self.assertEqual(h1.shape(0), 5)
for h in (h0, h1):
self.assertEqual(h[0], 2)
self.assertEqual(h[1], 1)
self.assertEqual(h[2], 3)
with self.assertRaises(TypeError):
h[0, 1]
self.assertEqual(h.value(0), 2)
self.assertEqual(h.value(1), 1)
self.assertEqual(h.value(2), 3)
with self.assertRaises(RuntimeError):
h.value(0, 1)
self.assertEqual(h1[-1], 1)
self.assertEqual(h1[3], 1)
self.assertEqual(h1.value(-1), 1)
self.assertEqual(h1.value(3), 1)
def test_growth(self):
h = histogram(integer_axis(-1, 1))
@ -374,11 +374,11 @@ class histogram_test(unittest.TestCase):
self.assertEqual(h.depth, 2)
for i in xrange(1000-256):
h.fill(0)
self.assertEqual(h[-1], 0)
self.assertEqual(h[0], 1)
self.assertEqual(h[1], 1000)
self.assertEqual(h[2], 2)
self.assertEqual(h[3], 0)
self.assertEqual(h.value(-1), 0)
self.assertEqual(h.value(0), 1)
self.assertEqual(h.value(1), 1000)
self.assertEqual(h.value(2), 2)
self.assertEqual(h.value(3), 0)
def test_fill_2d(self):
for uoflow in (False, True):
@ -403,12 +403,12 @@ class histogram_test(unittest.TestCase):
[0, 0, 0, 0, 0, 0]]
for i in xrange(h.axis(0).bins + 2*uoflow):
for j in xrange(h.axis(1).bins + 2*uoflow):
self.assertEqual(h[i, j], m[i][j])
self.assertEqual(h.value(i, j), m[i][j])
def test_add_2d(self):
for uoflow in (False, True):
h = histogram(integer_axis(-1, 1, uoflow=uoflow),
regular_axis(4, -2, 2, uoflow=uoflow))
regular_axis(4, -2, 2, uoflow=uoflow))
h.fill(-1, -2)
h.fill(-1, -1)
h.fill(0, 0)
@ -429,9 +429,47 @@ class histogram_test(unittest.TestCase):
for i in xrange(h.axis(0).bins + 2*uoflow):
for j in xrange(h.axis(1).bins + 2*uoflow):
self.assertEqual(h[i, j], 2 * m[i][j])
self.assertEqual(h.value(i, j), 2 * m[i][j])
self.assertEqual(h.variance(i, j), 2 * m[i][j])
def test_pickle(self):
def test_add_2d_bad(self):
a = histogram(integer_axis(-1, 1))
b = histogram(regular_axis(3, -1, 1))
with self.assertRaises(RuntimeError):
a += b
def test_add_2d_w(self):
for uoflow in (False, True):
h = histogram(integer_axis(-1, 1, uoflow=uoflow),
regular_axis(4, -2, 2, uoflow=uoflow))
h.fill(-1, -2)
h.fill(-1, -1)
h.fill(0, 0)
h.fill(0, 1)
h.fill(1, 0)
h.fill(3, -1)
h.fill(0, -3)
m = [[1, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 1],
[0, 0, 1, 0, 0, 0],
[0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0]]
hw = histogram(integer_axis(-1, 1, uoflow=uoflow),
regular_axis(4, -2, 2, uoflow=uoflow))
hw.fill(0, 0, w=0)
h2 = h + hw
h += h
self.assertNotEqual(h, h2)
for i in xrange(h.axis(0).bins + 2*uoflow):
for j in xrange(h.axis(1).bins + 2*uoflow):
self.assertEqual(h.value(i, j), 2 * m[i][j])
self.assertEqual(h.variance(i, j), 2 * m[i][j])
def test_pickle_0(self):
a = histogram(category_axis('A', 'B', 'C'),
integer_axis(0, 3, label='ia'),
regular_axis(4, 0.0, 4.0, uoflow=False),
@ -458,8 +496,35 @@ class histogram_test(unittest.TestCase):
self.assertEqual(a.sum, b.sum)
self.assertEqual(a, b)
def test_pickle_1(self):
a = histogram(category_axis('A', 'B', 'C'),
integer_axis(0, 3, label='ia'),
regular_axis(4, 0.0, 4.0, uoflow=False),
variable_axis(0.0, 1.0, 2.0))
for i in xrange(a.axis(0).bins):
a.fill(i, 0, 0, 0, w=3)
for j in xrange(a.axis(1).bins):
a.fill(i, j, 0, 0, w=10)
for k in xrange(a.axis(2).bins):
a.fill(i, j, k, 0, w=2)
for l in xrange(a.axis(3).bins):
a.fill(i, j, k, l, w=5)
io = StringIO.StringIO()
cPickle.dump(a, io)
io.seek(0)
b = cPickle.load(io)
self.assertNotEqual(id(a), id(b))
self.assertEqual(a.dim, b.dim)
self.assertEqual(a.axis(0), b.axis(0))
self.assertEqual(a.axis(1), b.axis(1))
self.assertEqual(a.axis(2), b.axis(2))
self.assertEqual(a.axis(3), b.axis(3))
self.assertEqual(a.sum, b.sum)
self.assertEqual(a, b)
@unittest.skipUnless("numpy" in globals(), "requires numpy")
def test_numpy_conversion(self):
def test_numpy_conversion_0(self):
a = histogram(integer_axis(0, 2, uoflow=False))
for i in xrange(100):
a.fill(1)
@ -480,25 +545,63 @@ class histogram_test(unittest.TestCase):
self.assertFalse(numpy.all(v == b))
@unittest.skipUnless("numpy" in globals(), "requires numpy")
def test_fill_with_numpy_array(self):
def test_numpy_conversion_1(self):
a = histogram(integer_axis(0, 2, uoflow=False))
for i in xrange(10):
a.fill(1, w=3)
b = numpy.array(a) # a copy
v = numpy.asarray(a) # a view
self.assertEqual(b.dtype, numpy.float64)
self.assertTrue(numpy.all(b == numpy.array(((0, 0), (30, 90), (0, 0)))))
self.assertTrue(numpy.all(v == b))
@unittest.skipUnless("numpy" in globals(), "requires numpy")
def test_fill_with_numpy_array_0(self):
a = histogram(integer_axis(0, 2, uoflow=False))
a.fill(numpy.array([-1, 0, 1, 2, 1, 4]))
self.assertEqual(a[0], 1)
self.assertEqual(a[1], 2)
self.assertEqual(a[2], 1)
self.assertEqual(a.value(0), 1)
self.assertEqual(a.value(1), 2)
self.assertEqual(a.value(2), 1)
with self.assertRaises(ValueError):
a.fill(numpy.empty((2, 2)))
with self.assertRaises(RuntimeError):
a.fill(numpy.empty((2, 1)), 1)
a = histogram(integer_axis(0, 1, uoflow=False),
regular_axis(2, 0, 2, uoflow=False))
regular_axis(2, 0, 2, uoflow=False))
a.fill(numpy.array([[-1., -1.], [0., 1.], [1., 0.1]]))
self.assertEqual(a[0, 0], 0)
self.assertEqual(a[0, 1], 1)
self.assertEqual(a[1, 0], 1)
self.assertEqual(a[1, 1], 0)
self.assertEqual(a.value(0, 0), 0)
self.assertEqual(a.value(0, 1), 1)
self.assertEqual(a.value(1, 0), 1)
self.assertEqual(a.value(1, 1), 0)
a = histogram(integer_axis(0, 2, uoflow=False))
a.fill([0, 0, 1, 2])
a.fill((1, 0, 2, 2))
self.assertEqual(a[0], 3)
self.assertEqual(a[1], 2)
self.assertEqual(a[2], 3)
self.assertEqual(a.value(0), 3)
self.assertEqual(a.value(1), 2)
self.assertEqual(a.value(2), 3)
@unittest.skipUnless("numpy" in globals(), "requires numpy")
def test_fill_with_numpy_array_1(self):
a = histogram(integer_axis(0, 2, uoflow=False))
a.fill(numpy.array([-1, 0, 1, 2, 1, 4]),
w=numpy.array([2.0, 3.0, 4.0, 5.0, 6.0, 7.0]))
self.assertEqual(a.value(0), 1)
self.assertEqual(a.value(1), 2)
self.assertEqual(a.value(2), 1)
a = histogram(integer_axis(0, 1, uoflow=False),
regular_axis(2, 0, 2, uoflow=False))
a.fill(numpy.array([[-1., -1.], [0., 1.], [1., 0.1]]))
self.assertEqual(a.value(0, 0), 0)
self.assertEqual(a.value(0, 1), 1)
self.assertEqual(a.value(1, 0), 1)
self.assertEqual(a.value(1, 1), 0)
a = histogram(integer_axis(0, 2, uoflow=False))
a.fill([0, 0, 1, 2])
a.fill((1, 0, 2, 2))
self.assertEqual(a.value(0), 3)
self.assertEqual(a.value(1), 2)
self.assertEqual(a.value(2), 3)
if __name__ == "__main__":
unittest.main()